This is code used to make plots based on output from the “IndividualPondModels_Forecasts85” for boththe CR and YF Read in the output files for each pond/RCP combination then work on delta figures and figures like Hamlet et al. 2020

rm(list = ls())

library(tidyverse)
library(dplyr)
library(rjags)
library(ggplot2)
library(matrixStats)

set.seed(1)

Starting with the Copper River Delta

RCP 45

Reading in the data

Mod_CRD45 <- read.csv("Corr_Mod_CRD45.csv", header = T)

2012-2020

# List of unique pond names from the dataframe
pond_names <- unique(Mod_CRD45$pond_name)

# Initialize an empty dataframe to store results
avgMed_2020 <- data.frame(Pond = pond_names, AvgMed_2020 = numeric(length(pond_names)))

# Loop through each pond name
for (i in seq_along(pond_names)) {
  pond_name <- pond_names[i]
  
  # Filter data for the current pond and for dates before January 1, 2021
  filtered_data <- Mod_CRD45 %>%
    filter(pond_name == !!pond_name, as.Date(time) < as.Date("2021-01-01"))
  
  # Calculate the mean of 'med' (which corresponds to X50%)
  avg_med <- mean(filtered_data$med, na.rm = TRUE)
  
  # Store the result in the dataframe
  avgMed_2020[i, "AvgMed_2020"] <- avg_med
}

# Print the dataframe
print(avgMed_2020)

2030-2039

library(lubridate)
library(dplyr)
library(tidyr)
library(ggplot2)

# List of unique pond names from the dataframe
pond_names <- unique(Mod_CRD45$pond_name)

# Initialize a dataframe to store results with years as columns
avgMed_2030 <- data.frame(Pond = pond_names)

# Loop through each year from 2030 to 2039
for (yr in 2030:2039) {
  # Calculate average medians for each year and store as a new column
  avgMed_col <- sapply(pond_names, function(pond_name) {
    yearly_data <- Mod_CRD45 %>%
      filter(pond_name == !!pond_name, year(as.Date(time)) == yr)
    
    avg_med <- mean(yearly_data$med, na.rm = TRUE)
    return(avg_med)
  })
  
  # Add the results as a new column to the dataframe
  avgMed_2030[[as.character(yr)]] <- avgMed_col
}

# Print the final dataframe
print(avgMed_2030)

# Convert to long format for ggplot2
avgMed_2030_long <- avgMed_2030 %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "AvgMed")

# Plot the data
ggplot(avgMed_2030_long, aes(x = Year, y = AvgMed, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  labs(title = "Average Median per Pond from 2030 to 2039",
       x = "Year",
       y = "Average Median") +
  theme_minimal()

2060-2069

library(lubridate)
library(dplyr)
library(tidyr)
library(ggplot2)

# List of unique pond names from the dataframe
pond_names <- unique(Mod_CRD45$pond_name)

# Initialize a dataframe to store results with years as columns
avgMed_2060 <- data.frame(Pond = pond_names)

# Loop through each year from 2060 to 2069
for (yr in 2060:2069) {
  # Calculate average medians for each year and store as a new column
  avgMed_col <- sapply(pond_names, function(pond_name) {
    yearly_data <- Mod_CRD45 %>%
      filter(pond_name == !!pond_name, year(as.Date(time)) == yr)
    
    avg_med <- mean(yearly_data$med, na.rm = TRUE)
    return(avg_med)
  })
  
  # Add the results as a new column to the dataframe
  avgMed_2060[[as.character(yr)]] <- avgMed_col
}

# Print the final dataframe
print(avgMed_2060)

# Convert to long format for ggplot2
avgMed_2060_long <- avgMed_2060 %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "AvgMed")

# Plot the data
ggplot(avgMed_2060_long, aes(x = Year, y = AvgMed, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  labs(title = "Average Median per Pond from 2060 to 2069",
       x = "Year",
       y = "Average Median") +
  theme_minimal()

2090-2099

library(lubridate)
library(dplyr)
library(tidyr)
library(ggplot2)

# List of unique pond names from the dataframe
pond_names <- unique(Mod_CRD45$pond_name)

# Initialize a dataframe to store results with years as columns
avgMed_2090 <- data.frame(Pond = pond_names)

# Loop through each year from 2090 to 2099
for (yr in 2090:2099) {
  # Calculate average medians for each year and store as a new column
  avgMed_col <- sapply(pond_names, function(pond_name) {
    yearly_data <- Mod_CRD45 %>%
      filter(pond_name == !!pond_name, year(as.Date(time)) == yr)
    
    avg_med <- mean(yearly_data$med, na.rm = TRUE)
    return(avg_med)
  })
  
  # Add the results as a new column to the dataframe
  avgMed_2090[[as.character(yr)]] <- avgMed_col
}

# Print the final dataframe
print(avgMed_2090)

# Convert to long format for ggplot2
avgMed_2090_long <- avgMed_2090 %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "AvgMed")

# Plot the data
ggplot(avgMed_2090_long, aes(x = Year, y = AvgMed, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  labs(title = "Average Median per Pond from 2090 to 2099",
       x = "Year",
       y = "Average Median") +
  theme_minimal()

# Rename columns to reflect only the years
avgMed_2020 <- avgMed_2020 %>%
  rename(AvgMed_2020 = AvgMed_2020)

avgMed_2030 <- avgMed_2030 %>%
  rename(`2030` = `2030`)

avgMed_2060 <- avgMed_2060 %>%
  rename(`2060` = `2060`)

avgMed_2090 <- avgMed_2090 %>%
  rename(`2090` = `2090`)

# Combine the data frames
combined_avgMed <- avgMed_2020 %>%
  left_join(avgMed_2030, by = "Pond") %>%
  left_join(avgMed_2060, by = "Pond") %>%
  left_join(avgMed_2090, by = "Pond")

# Print the final dataframe
print(combined_avgMed)

# Convert to long format for ggplot2, excluding AvgMed_2020
avgMed_long <- combined_avgMed %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "AvgMed") %>%
  filter(Year %in% as.character(2021:2199))

# Plot the data
ggplot(avgMed_long, aes(x = Year, y = AvgMed, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  labs(title = "Average Median per Pond in the CRD - RCP 4.5",
       x = "Year",
       y = "Average Median") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),# Rotate x-axis labels by 45 degrees
        plot.title = element_text(hjust = 0.5))  

Calcuate the differences here as new columns in the dataframe

library(dplyr)

# Assuming combined_avgMed is loaded and structure verified
Delta_combined_avgMed <- combined_avgMed  # Use your actual dataframe

# Columns to calculate differences for
years <- c("2030", "2031", "2032", "2033", "2034", 
           "2035", "2036", "2037", "2038", "2039", 
           "2060", "2061", "2062", "2063", "2064", 
           "2065", "2066", "2067", "2068", "2069", 
           "2090", "2091", "2092", "2093", "2094", 
           "2095", "2096", "2097", "2098", "2099")

# Loop through each year and calculate the difference
for (year in years) {
  # Create a new column for the difference
  diff_col_name <- paste0("diff_", year)
  Delta_combined_avgMed[[diff_col_name]] <- Delta_combined_avgMed[[year]] - Delta_combined_avgMed$`AvgMed_2020`
}

# Display the structure of Delta_combined_avgMed to verify
str(Delta_combined_avgMed)
'data.frame':   9 obs. of  62 variables:
 $ Pond       : chr  "BVS" "CAB" "TIN" "SQR" ...
 $ AvgMed_2020: num  5.65 5.89 7.64 8.4 8.45 ...
 $ 2030       : num  7 7.24 9 9.76 9.84 ...
 $ 2031       : num  7.98 8.21 9.97 10.75 10.81 ...
 $ 2032       : num  9.19 9.44 11.2 11.97 12.03 ...
 $ 2033       : num  7.49 7.73 9.49 10.27 10.32 ...
 $ 2034       : num  8.21 8.44 10.2 10.97 11.03 ...
 $ 2035       : num  4.74 4.98 6.73 7.52 7.58 ...
 $ 2036       : num  6.1 6.34 8.08 8.9 8.93 ...
 $ 2037       : num  8.6 8.83 10.6 11.35 11.42 ...
 $ 2038       : num  7.41 7.67 9.41 10.18 10.24 ...
 $ 2039       : num  8.16 8.41 10.16 10.92 10.97 ...
 $ 2060       : num  9.49 9.73 11.49 12.27 12.32 ...
 $ 2061       : num  9.33 9.57 11.32 12.08 12.16 ...
 $ 2062       : num  9.9 10.1 11.9 12.7 12.7 ...
 $ 2063       : num  10.8 11.1 12.8 13.6 13.6 ...
 $ 2064       : num  8.14 8.4 10.16 10.92 10.97 ...
 $ 2065       : num  10.2 10.4 12.2 13 13 ...
 $ 2066       : num  9.03 9.27 11.03 11.8 11.86 ...
 $ 2067       : num  8.53 8.77 10.52 11.3 11.36 ...
 $ 2068       : num  9.23 9.46 11.21 11.98 12.05 ...
 $ 2069       : num  10.1 10.4 12.1 12.9 12.9 ...
 $ 2090       : num  9.64 9.9 11.66 12.42 12.48 ...
 $ 2091       : num  11.2 11.5 13.2 14 14 ...
 $ 2092       : num  11.8 12.1 13.8 14.6 14.7 ...
 $ 2093       : num  10.6 10.8 12.6 13.4 13.4 ...
 $ 2094       : num  10.9 11.2 12.9 13.7 13.7 ...
 $ 2095       : num  10.9 11.1 12.9 13.7 13.7 ...
 $ 2096       : num  11.5 11.7 13.5 14.3 14.3 ...
 $ 2097       : num  10.6 10.8 12.6 13.4 13.4 ...
 $ 2098       : num  10.5 10.8 12.5 13.3 13.4 ...
 $ 2099       : num  11.6 11.8 13.6 14.4 14.4 ...
 $ diff_2030  : num  1.35 1.35 1.37 1.36 1.38 ...
 $ diff_2031  : num  2.32 2.32 2.33 2.34 2.36 ...
 $ diff_2032  : num  3.54 3.54 3.57 3.57 3.57 ...
 $ diff_2033  : num  1.84 1.84 1.86 1.86 1.87 ...
 $ diff_2034  : num  2.56 2.54 2.56 2.56 2.57 ...
 $ diff_2035  : num  -0.914 -0.919 -0.903 -0.888 -0.878 ...
 $ diff_2036  : num  0.444 0.449 0.446 0.495 0.477 ...
 $ diff_2037  : num  2.94 2.94 2.97 2.94 2.97 ...
 $ diff_2038  : num  1.75 1.77 1.78 1.77 1.78 ...
 $ diff_2039  : num  2.51 2.52 2.52 2.52 2.52 ...
 $ diff_2060  : num  3.84 3.84 3.85 3.86 3.87 ...
 $ diff_2061  : num  3.67 3.67 3.69 3.68 3.7 ...
 $ diff_2062  : num  4.24 4.24 4.26 4.27 4.27 ...
 $ diff_2063  : num  5.16 5.18 5.18 5.17 5.18 ...
 $ diff_2064  : num  2.49 2.5 2.52 2.52 2.51 ...
 $ diff_2065  : num  4.53 4.54 4.54 4.55 4.56 ...
 $ diff_2066  : num  3.38 3.37 3.4 3.39 3.4 ...
 $ diff_2067  : num  2.88 2.87 2.89 2.9 2.91 ...
 $ diff_2068  : num  3.57 3.57 3.57 3.58 3.59 ...
 $ diff_2069  : num  4.45 4.46 4.47 4.48 4.48 ...
 $ diff_2090  : num  3.99 4 4.02 4.01 4.03 ...
 $ diff_2091  : num  5.55 5.57 5.56 5.56 5.59 ...
 $ diff_2092  : num  6.18 6.18 6.19 6.2 6.22 ...
 $ diff_2093  : num  4.93 4.93 4.95 4.96 4.95 ...
 $ diff_2094  : num  5.27 5.29 5.29 5.3 5.29 ...
 $ diff_2095  : num  5.24 5.24 5.26 5.27 5.26 ...
 $ diff_2096  : num  5.84 5.84 5.86 5.85 5.87 ...
 $ diff_2097  : num  4.93 4.94 4.95 4.96 4.96 ...
 $ diff_2098  : num  4.87 4.86 4.89 4.89 4.9 ...
 $ diff_2099  : num  5.94 5.95 5.96 5.96 5.97 ...
# Create a new dataframe with the calculated means and standard deviations
Delta_CRD45 <- Delta_combined_avgMed %>%
  mutate(
    Mean_2030_2039 = rowMeans(select(., starts_with("diff_203")), na.rm = TRUE),  # Calculate row-wise mean for columns starting with "diff_203"
    SD_2030_2039 = rowSds(as.matrix(select(., starts_with("diff_203"))), na.rm = TRUE),  # Calculate row-wise SD for columns starting with "diff_203"
    Mean_2060_2069 = rowMeans(select(., starts_with("diff_206")), na.rm = TRUE),  # Calculate row-wise mean for columns starting with "diff_206"
    SD_2060_2069 = rowSds(as.matrix(select(., starts_with("diff_206"))), na.rm = TRUE),  # Calculate row-wise SD for columns starting with "diff_206"
    Mean_2090_2099 = rowMeans(select(., starts_with("diff_209")), na.rm = TRUE),  # Calculate row-wise mean for columns starting with "diff_209"
    SD_2090_2099 = rowSds(as.matrix(select(., starts_with("diff_209"))), na.rm = TRUE)  # Calculate row-wise SD for columns starting with "diff_209"
  )

# Print the structure of the new dataframe
str(Delta_CRD45)
'data.frame':   9 obs. of  68 variables:
 $ Pond          : chr  "BVS" "CAB" "TIN" "SQR" ...
 $ AvgMed_2020   : num  5.65 5.89 7.64 8.4 8.45 ...
 $ 2030          : num  7 7.24 9 9.76 9.84 ...
 $ 2031          : num  7.98 8.21 9.97 10.75 10.81 ...
 $ 2032          : num  9.19 9.44 11.2 11.97 12.03 ...
 $ 2033          : num  7.49 7.73 9.49 10.27 10.32 ...
 $ 2034          : num  8.21 8.44 10.2 10.97 11.03 ...
 $ 2035          : num  4.74 4.98 6.73 7.52 7.58 ...
 $ 2036          : num  6.1 6.34 8.08 8.9 8.93 ...
 $ 2037          : num  8.6 8.83 10.6 11.35 11.42 ...
 $ 2038          : num  7.41 7.67 9.41 10.18 10.24 ...
 $ 2039          : num  8.16 8.41 10.16 10.92 10.97 ...
 $ 2060          : num  9.49 9.73 11.49 12.27 12.32 ...
 $ 2061          : num  9.33 9.57 11.32 12.08 12.16 ...
 $ 2062          : num  9.9 10.1 11.9 12.7 12.7 ...
 $ 2063          : num  10.8 11.1 12.8 13.6 13.6 ...
 $ 2064          : num  8.14 8.4 10.16 10.92 10.97 ...
 $ 2065          : num  10.2 10.4 12.2 13 13 ...
 $ 2066          : num  9.03 9.27 11.03 11.8 11.86 ...
 $ 2067          : num  8.53 8.77 10.52 11.3 11.36 ...
 $ 2068          : num  9.23 9.46 11.21 11.98 12.05 ...
 $ 2069          : num  10.1 10.4 12.1 12.9 12.9 ...
 $ 2090          : num  9.64 9.9 11.66 12.42 12.48 ...
 $ 2091          : num  11.2 11.5 13.2 14 14 ...
 $ 2092          : num  11.8 12.1 13.8 14.6 14.7 ...
 $ 2093          : num  10.6 10.8 12.6 13.4 13.4 ...
 $ 2094          : num  10.9 11.2 12.9 13.7 13.7 ...
 $ 2095          : num  10.9 11.1 12.9 13.7 13.7 ...
 $ 2096          : num  11.5 11.7 13.5 14.3 14.3 ...
 $ 2097          : num  10.6 10.8 12.6 13.4 13.4 ...
 $ 2098          : num  10.5 10.8 12.5 13.3 13.4 ...
 $ 2099          : num  11.6 11.8 13.6 14.4 14.4 ...
 $ diff_2030     : num  1.35 1.35 1.37 1.36 1.38 ...
 $ diff_2031     : num  2.32 2.32 2.33 2.34 2.36 ...
 $ diff_2032     : num  3.54 3.54 3.57 3.57 3.57 ...
 $ diff_2033     : num  1.84 1.84 1.86 1.86 1.87 ...
 $ diff_2034     : num  2.56 2.54 2.56 2.56 2.57 ...
 $ diff_2035     : num  -0.914 -0.919 -0.903 -0.888 -0.878 ...
 $ diff_2036     : num  0.444 0.449 0.446 0.495 0.477 ...
 $ diff_2037     : num  2.94 2.94 2.97 2.94 2.97 ...
 $ diff_2038     : num  1.75 1.77 1.78 1.77 1.78 ...
 $ diff_2039     : num  2.51 2.52 2.52 2.52 2.52 ...
 $ diff_2060     : num  3.84 3.84 3.85 3.86 3.87 ...
 $ diff_2061     : num  3.67 3.67 3.69 3.68 3.7 ...
 $ diff_2062     : num  4.24 4.24 4.26 4.27 4.27 ...
 $ diff_2063     : num  5.16 5.18 5.18 5.17 5.18 ...
 $ diff_2064     : num  2.49 2.5 2.52 2.52 2.51 ...
 $ diff_2065     : num  4.53 4.54 4.54 4.55 4.56 ...
 $ diff_2066     : num  3.38 3.37 3.4 3.39 3.4 ...
 $ diff_2067     : num  2.88 2.87 2.89 2.9 2.91 ...
 $ diff_2068     : num  3.57 3.57 3.57 3.58 3.59 ...
 $ diff_2069     : num  4.45 4.46 4.47 4.48 4.48 ...
 $ diff_2090     : num  3.99 4 4.02 4.01 4.03 ...
 $ diff_2091     : num  5.55 5.57 5.56 5.56 5.59 ...
 $ diff_2092     : num  6.18 6.18 6.19 6.2 6.22 ...
 $ diff_2093     : num  4.93 4.93 4.95 4.96 4.95 ...
 $ diff_2094     : num  5.27 5.29 5.29 5.3 5.29 ...
 $ diff_2095     : num  5.24 5.24 5.26 5.27 5.26 ...
 $ diff_2096     : num  5.84 5.84 5.86 5.85 5.87 ...
 $ diff_2097     : num  4.93 4.94 4.95 4.96 4.96 ...
 $ diff_2098     : num  4.87 4.86 4.89 4.89 4.9 ...
 $ diff_2099     : num  5.94 5.95 5.96 5.96 5.97 ...
 $ Mean_2030_2039: num  1.83 1.83 1.85 1.85 1.86 ...
 $ SD_2030_2039  : num  1.29 1.29 1.3 1.29 1.29 ...
 $ Mean_2060_2069: num  3.82 3.82 3.84 3.84 3.85 ...
 $ SD_2060_2069  : num  0.803 0.807 0.802 0.803 0.805 ...
 $ Mean_2090_2099: num  5.27 5.28 5.29 5.3 5.3 ...
 $ SD_2090_2099  : num  0.642 0.641 0.637 0.639 0.643 ...
# Optionally, view the first few rows to check the new columns
head(Delta_CRD45)

Put these into total mean/standard deviations

# Load necessary libraries
library(dplyr)

# Select and rename columns from Delta_CRD45
CRD45_decadal <- Delta_CRD45 %>%
  select(Pond, starts_with("Mean_"), starts_with("SD_"))

# Rename columns without the 'Y' prefix for means
names(CRD45_decadal) <- sub("^Mean_", "Mean_", names(CRD45_decadal))

# Rename columns without the 'Y' prefix for standard deviations
names(CRD45_decadal) <- sub("^SD_", "SD_", names(CRD45_decadal))

# Print the structure of the updated dataframe
str(CRD45_decadal)
'data.frame':   9 obs. of  7 variables:
 $ Pond          : chr  "BVS" "CAB" "TIN" "SQR" ...
 $ Mean_2030_2039: num  1.83 1.83 1.85 1.85 1.86 ...
 $ Mean_2060_2069: num  3.82 3.82 3.84 3.84 3.85 ...
 $ Mean_2090_2099: num  5.27 5.28 5.29 5.3 5.3 ...
 $ SD_2030_2039  : num  1.29 1.29 1.3 1.29 1.29 ...
 $ SD_2060_2069  : num  0.803 0.807 0.802 0.803 0.805 ...
 $ SD_2090_2099  : num  0.642 0.641 0.637 0.639 0.643 ...
# Optionally, view the first few rows to check the new columns
head(CRD45_decadal)

Making the plots of these deltas

# Load required packages
library(ggplot2)
library(gridExtra)
library(ggpubr)

# Create a grouped bar plot with error bars for Mean 2030
plot_2030 <- ggplot(CRD45_decadal, aes(x = Pond, y = Mean_2030_2039)) +
  geom_bar(stat = "identity", fill = "#FFD92F", color = "black") +
  geom_errorbar(aes(ymin = Mean_2030_2039 - SD_2030_2039, ymax = Mean_2030_2039 + SD_2030_2039),
                width = 0.4,  # Adjust the width of error bars as needed
                position = position_dodge(width = 0.9)) +
  labs(x = "", y = "Delta Temp (C)") +
  ylim(-1, 5) +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(plot.title = element_text(hjust = 0.5))  # Centered title
plot_2030


# Create a grouped bar plot with error bars for Mean 2060
plot_2060 <- ggplot(CRD45_decadal, aes(x = Pond, y = Mean_2060_2069)) +
  geom_bar(stat = "identity", fill = "#F46D43", color = "black") +
  geom_errorbar(aes(ymin = Mean_2060_2069 - SD_2060_2069, ymax = Mean_2060_2069 + SD_2060_2069),
                width = 0.4,  # Adjust the width of error bars as needed
                position = position_dodge(width = 0.9)) +
  labs(x = "", y = "") +  # No y-axis label
  ylim(-1, 5) +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(plot.title = element_text(hjust = 0.5)) +  # Centered title 
  theme(axis.text.y = element_blank(),  # Remove Y-axis tick mark labels
        axis.ticks.y = element_blank())   # Remove Y-axis ticks
plot_2060


# Create a grouped bar plot with error bars for Mean 2090
plot_2090 <- ggplot(CRD45_decadal, aes(x = Pond, y = Mean_2090_2099)) +
  geom_bar(stat = "identity", fill = "#D73027", color = "black") +
  geom_errorbar(aes(ymin = Mean_2090_2099 - SD_2090_2099, ymax = Mean_2090_2099 + SD_2090_2099),
                width = 0.4,  # Adjust the width of error bars as needed
                position = position_dodge(width = 0.9)) +
  labs(x = "", y = "") +  # No y-axis label
  ylim(-1, 5) +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(plot.title = element_text(hjust = 0.5)) +  # Centered title 
  theme(axis.text.y = element_blank(),  # Remove Y-axis tick mark labels
        axis.ticks.y = element_blank())   # Remove Y-axis ticks
plot_2090
Warning: Removed 9 rows containing missing values or values outside the scale range (`geom_bar()`).
# Combine plots into a panel plot
Delta_CRD45_plot <- ggarrange(plot_2030, plot_2060, plot_2090, ncol = 3)
Warning: Removed 9 rows containing missing values or values outside the scale range (`geom_bar()`).
# Save the combined plot
ggsave("Corr_DeltaCRD45.png", plot = Delta_CRD45_plot, width = 8, height = 3)

Statistical tests for each of these ponds for 2030s, 2060s, and 2090s

2030s

Delta_CRD45

# Load required libraries
library(dplyr)
library(broom)
library(tidyr)

# Step 1: Prepare the data
data_long <- Delta_CRD45 %>%
  select(Pond, matches("^diff_203[0-9]$")) %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "Difference")

boxplot(data_long$Difference ~ data_long$Pond)


# Step 2: Conduct ANOVA by grouping by Pond
res_CRD45 <- aov(Difference ~ Pond, data = data_long)
summary(res_CRD45)
            Df Sum Sq Mean Sq F value Pr(>F)
Pond         8   0.01  0.0012   0.001      1
Residuals   81 135.53  1.6732               
# Step 3: Tukey HSD
post_test_CRD45 <- TukeyHSD(res_CRD45)
post_test_CRD45
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Difference ~ Pond, data = data_long)

$Pond
                 diff       lwr      upr p adj
CAB-BVS  1.214803e-03 -1.842514 1.844943     1
CAN-BVS  2.805931e-02 -1.815669 1.871788     1
EYS-BVS  2.289556e-02 -1.820833 1.866624     1
RHM-BVS  1.206862e-03 -1.842522 1.844935     1
SQR-BVS  2.018862e-02 -1.823540 1.863917     1
TIN-BVS  1.588325e-02 -1.827845 1.859612     1
TIS-BVS  1.889326e-02 -1.824835 1.862622     1
WDD-BVS  2.287431e-02 -1.820854 1.866603     1
CAN-CAB  2.684451e-02 -1.816884 1.870573     1
EYS-CAB  2.168076e-02 -1.822048 1.865409     1
RHM-CAB -7.940660e-06 -1.843737 1.843721     1
SQR-CAB  1.897381e-02 -1.824755 1.862702     1
TIN-CAB  1.466845e-02 -1.829060 1.858397     1
TIS-CAB  1.767845e-02 -1.826050 1.861407     1
WDD-CAB  2.165951e-02 -1.822069 1.865388     1
EYS-CAN -5.163752e-03 -1.848892 1.838565     1
RHM-CAN -2.685245e-02 -1.870581 1.816876     1
SQR-CAN -7.870694e-03 -1.851599 1.835858     1
TIN-CAN -1.217606e-02 -1.855905 1.831553     1
TIS-CAN -9.166053e-03 -1.852895 1.834563     1
WDD-CAN -5.185002e-03 -1.848914 1.838544     1
RHM-EYS -2.168870e-02 -1.865417 1.822040     1
SQR-EYS -2.706942e-03 -1.846436 1.841022     1
TIN-EYS -7.012306e-03 -1.850741 1.836716     1
TIS-EYS -4.002301e-03 -1.847731 1.839726     1
WDD-EYS -2.124991e-05 -1.843750 1.843707     1
SQR-RHM  1.898175e-02 -1.824747 1.862710     1
TIN-RHM  1.467639e-02 -1.829052 1.858405     1
TIS-RHM  1.768640e-02 -1.826042 1.861415     1
WDD-RHM  2.166745e-02 -1.822061 1.865396     1
TIN-SQR -4.305364e-03 -1.848034 1.839423     1
TIS-SQR -1.295359e-03 -1.845024 1.842433     1
WDD-SQR  2.685692e-03 -1.841043 1.846414     1
TIS-TIN  3.010005e-03 -1.840719 1.846739     1
WDD-TIN  6.991056e-03 -1.836738 1.850720     1
WDD-TIS  3.981051e-03 -1.839748 1.847710     1

2060s

Delta_CRD45

# Load required libraries
library(dplyr)
library(broom)

# Step 1: Prepare the data
data_long <- Delta_CRD45 %>%
  select(Pond, matches("^diff_206[0-9]$")) %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "Difference")

boxplot(data_long$Difference ~ data_long$Pond)


# Step 2: Conduct ANOVA by grouping by Pond
res_CRD45 <- aov(Difference ~ Pond, data = data_long)
summary(res_CRD45)
            Df Sum Sq Mean Sq F value Pr(>F)
Pond         8   0.01  0.0013   0.002      1
Residuals   81  52.61  0.6495               
# Step 3: Tukey HSD
post_test_CRD45 <- TukeyHSD(res_CRD45)
post_test_CRD45
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Difference ~ Pond, data = data_long)

$Pond
                 diff       lwr      upr p adj
CAB-BVS  0.0035901603 -1.145125 1.152306     1
CAN-BVS  0.0283876339 -1.120328 1.177103     1
EYS-BVS  0.0195832180 -1.129132 1.168299     1
RHM-BVS -0.0013213523 -1.150037 1.147394     1
SQR-BVS  0.0188165617 -1.129899 1.167532     1
TIN-BVS  0.0160150233 -1.132701 1.164731     1
TIS-BVS  0.0177892348 -1.130926 1.166505     1
WDD-BVS  0.0292115139 -1.119504 1.177927     1
CAN-CAB  0.0247974736 -1.123918 1.173513     1
EYS-CAB  0.0159930576 -1.132723 1.164709     1
RHM-CAB -0.0049115127 -1.153627 1.143804     1
SQR-CAB  0.0152264014 -1.133489 1.163942     1
TIN-CAB  0.0124248630 -1.136291 1.161140     1
TIS-CAB  0.0141990745 -1.134517 1.162915     1
WDD-CAB  0.0256213535 -1.123094 1.174337     1
EYS-CAN -0.0088044159 -1.157520 1.139911     1
RHM-CAN -0.0297089862 -1.178425 1.119007     1
SQR-CAN -0.0095710722 -1.158287 1.139145     1
TIN-CAN -0.0123726106 -1.161088 1.136343     1
TIS-CAN -0.0105983991 -1.159314 1.138117     1
WDD-CAN  0.0008238800 -1.147892 1.149539     1
RHM-EYS -0.0209045703 -1.169620 1.127811     1
SQR-EYS -0.0007666563 -1.149482 1.147949     1
TIN-EYS -0.0035681947 -1.152284 1.145147     1
TIS-EYS -0.0017939831 -1.150510 1.146922     1
WDD-EYS  0.0096282959 -1.139087 1.158344     1
SQR-RHM  0.0201379140 -1.128578 1.168854     1
TIN-RHM  0.0173363756 -1.131379 1.166052     1
TIS-RHM  0.0191105872 -1.129605 1.167826     1
WDD-RHM  0.0305328662 -1.118183 1.179248     1
TIN-SQR -0.0028015384 -1.151517 1.145914     1
TIS-SQR -0.0010273269 -1.149743 1.147688     1
WDD-SQR  0.0103949522 -1.138321 1.159111     1
TIS-TIN  0.0017742115 -1.146941 1.150490     1
WDD-TIN  0.0131964906 -1.135519 1.161912     1
WDD-TIS  0.0114222790 -1.137293 1.160138     1

2090s

Delta_CRD45

# Load required libraries
library(dplyr)
library(broom)

# Step 1: Prepare the data
data_long <- Delta_CRD45 %>%
  select(Pond, matches("^diff_209[0-9]$")) %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "Difference")

boxplot(data_long$Difference ~ data_long$Pond)


# Step 2: Conduct ANOVA by grouping by Pond
res_CRD45 <- aov(Difference ~ Pond, data = data_long)
summary(res_CRD45)
            Df Sum Sq Mean Sq F value Pr(>F)
Pond         8   0.01  0.0014   0.003      1
Residuals   81  33.39  0.4122               
# Step 3: Tukey HSD
post_test_CRD45 <- TukeyHSD(res_CRD45)
post_test_CRD45
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Difference ~ Pond, data = data_long)

$Pond
                diff        lwr       upr p adj
CAB-BVS  0.005808524 -0.9092851 0.9209022     1
CAN-BVS  0.031775890 -0.8833178 0.9468695     1
EYS-BVS  0.020810076 -0.8942836 0.9359037     1
RHM-BVS -0.001850173 -0.9169438 0.9132435     1
SQR-BVS  0.023209929 -0.8918837 0.9383036     1
TIN-BVS  0.018623321 -0.8964703 0.9337170     1
TIS-BVS  0.012662910 -0.9024307 0.9277566     1
WDD-BVS  0.024980879 -0.8901128 0.9400745     1
CAN-CAB  0.025967366 -0.8891263 0.9410610     1
EYS-CAB  0.015001551 -0.9000921 0.9300952     1
RHM-CAB -0.007658697 -0.9227524 0.9074350     1
SQR-CAB  0.017401405 -0.8976922 0.9324951     1
TIN-CAB  0.012814797 -0.9022789 0.9279085     1
TIS-CAB  0.006854386 -0.9082393 0.9219480     1
WDD-CAB  0.019172354 -0.8959213 0.9342660     1
EYS-CAN -0.010965815 -0.9260595 0.9041278     1
RHM-CAN -0.033626063 -0.9487197 0.8814676     1
SQR-CAN -0.008565961 -0.9236596 0.9065277     1
TIN-CAN -0.013152570 -0.9282462 0.9019411     1
TIS-CAN -0.019112980 -0.9342066 0.8959807     1
WDD-CAN -0.006795012 -0.9218887 0.9082986     1
RHM-EYS -0.022660248 -0.9377539 0.8924334     1
SQR-EYS  0.002399854 -0.9126938 0.9174935     1
TIN-EYS -0.002186755 -0.9172804 0.9129069     1
TIS-EYS -0.008147165 -0.9232408 0.9069465     1
WDD-EYS  0.004170803 -0.9109229 0.9192645     1
SQR-RHM  0.025060102 -0.8900336 0.9401538     1
TIN-RHM  0.020473494 -0.8946202 0.9355671     1
TIS-RHM  0.014513083 -0.9005806 0.9296067     1
WDD-RHM  0.026831051 -0.8882626 0.9419247     1
TIN-SQR -0.004586609 -0.9196803 0.9105070     1
TIS-SQR -0.010547019 -0.9256407 0.9045466     1
WDD-SQR  0.001770949 -0.9133227 0.9168646     1
TIS-TIN -0.005960411 -0.9210541 0.9091332     1
WDD-TIN  0.006357558 -0.9087361 0.9214512     1
WDD-TIS  0.012317968 -0.9027757 0.9274116     1

Making plots of error by season

2012-2020

# Extract unique pond names from the dataframe
short_names <- unique(Mod_CRD45$pond_name)

# Initialize an empty dataframe to store monthly mean results
monthly_means <- data.frame(Pond = character(), Month = character(), AvgTemp = numeric(), Year = numeric(), stringsAsFactors = FALSE)

# Convert 'time' column to Date class
Mod_CRD45$time <- as.Date(Mod_CRD45$time, format="%Y-%m-%d")

# Extract year and month from 'time' column
Mod_CRD45$Year <- format(Mod_CRD45$time, "%Y")
Mod_CRD45$Month <- format(Mod_CRD45$time, "%B")

# Loop through each unique pond name
for (short_name in short_names) {
  # Filter data for the current pond
  pond_data <- subset(Mod_CRD45, pond_name == short_name)
  
  # Loop through each month
  for (month in month.name) {
    # Filter data for the current month
    filtered_data <- subset(pond_data, Month == month)
    
    # Calculate the mean of 'med' for the current month
    avg_med <- mean(filtered_data$med, na.rm = TRUE)
    
    # Append results to monthly_means dataframe
    monthly_means <- rbind(monthly_means, data.frame(Pond = short_name, Month = month, AvgTemp = avg_med, Year = 2020))
  }
}

# Print the monthly means dataframe
print(monthly_means)

# Plotting the data
ggplot(monthly_means, aes(x = Month, y = AvgTemp, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  scale_x_discrete(limits = month.name) +
  labs(title = "Monthly Average Temperatures for Each Pond",
       x = "Month",
       y = "Average Temperature",
       color = "Pond") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

2030, 2060, and 2090

# Define the correct order for months
month_order <- c("January", "February", "March", "April", "May", "June", 
                  "July", "August", "September", "October", "November", "December")

# Recalculate monthly averages with correct month ordering
calculate_monthly_averages <- function(data, decade_start, decade_end) {
  # Initialize empty dataframe to store monthly averages
  monthly_avg_table <- data.frame(Pond = character(), Month = factor(), AvgTemp = numeric(), Year = integer(), stringsAsFactors = FALSE)
  
  # Loop through each year in the decade
  for (yr in decade_start:decade_end) {
    # Filter data for the current year
    yearly_data <- data %>%
      filter(year(time) == yr)
    
    # Loop through each pond
    for (pond_name in unique(data$pond_name)) {
      pond_data <- yearly_data %>%
        filter(pond_name == pond_name)
      
      # Loop through each month
      for (month in month_order) {
        # Filter data for the current month
        monthly_data <- pond_data %>%
          filter(format(time, "%B") == month)
        
        # Calculate the mean of 'med' for the current month
        avg_temp <- mean(monthly_data$med, na.rm = TRUE)
        
        # Append results to monthly_avg_table dataframe
        monthly_avg_table <- rbind(monthly_avg_table, data.frame(Pond = pond_name, Month = factor(month, levels = month_order), AvgTemp = avg_temp, Year = yr))
      }
    }
  }
  
  return(monthly_avg_table)
}

# Calculate monthly averages for each decade
monthly_avgX50_table_2030s <- calculate_monthly_averages(Mod_CRD45, 2030, 2039)
monthly_avgX50_table_2060s <- calculate_monthly_averages(Mod_CRD45, 2060, 2069)
monthly_avgX50_table_2090s <- calculate_monthly_averages(Mod_CRD45, 2090, 2099)

Combine all the monthly average tables into one dataframe

# Add a Decade column to each dataframe
monthly_means <- monthly_means %>%
  mutate(Decade = "2020s")

monthly_avgX50_table_2030s <- monthly_avgX50_table_2030s %>%
  mutate(Decade = "2030s")

monthly_avgX50_table_2060s <- monthly_avgX50_table_2060s %>%
  mutate(Decade = "2060s")

monthly_avgX50_table_2090s <- monthly_avgX50_table_2090s %>%
  mutate(Decade = "2090s")

# Combine all monthly average tables into one dataframe
combined_monthly_avg <- bind_rows(
  monthly_means,
  monthly_avgX50_table_2030s,
  monthly_avgX50_table_2060s,
  monthly_avgX50_table_2090s
)

# Print the combined dataframe
print(combined_monthly_avg)

Calculate the differences here as compared to 2020

# Define the reference year
reference_year <- 2020

# Check if the column exists and is correctly populated
summary(combined_monthly_avg)
     Pond              Month              AvgTemp            Year         Decade         
 Length:3348        Length:3348        Min.   :-1.329   Min.   :2020   Length:3348       
 Class :character   Class :character   1st Qu.: 7.762   1st Qu.:2036   Class :character  
 Mode  :character   Mode  :character   Median :11.285   Median :2064   Mode  :character  
                                       Mean   :10.913   Mean   :2063                     
                                       3rd Qu.:14.112   3rd Qu.:2092                     
                                       Max.   :17.872   Max.   :2099                     
# Calculate average temperature for each month in the reference year
ref_year_avg <- combined_monthly_avg %>%
  filter(Year == reference_year) %>%
  group_by(Month) %>%
  summarise(avg_temp_ref_year = mean(AvgTemp, na.rm = TRUE))

# Join reference year averages with the main dataset
combined_monthly_avg_with_diff <- combined_monthly_avg %>%
  left_join(ref_year_avg, by = "Month") %>%
  mutate(diff_AvgTemp = AvgTemp - avg_temp_ref_year) %>%
  select(-avg_temp_ref_year)  # Remove the reference year average column

# Display the structure to verify
str(combined_monthly_avg_with_diff)
'data.frame':   3348 obs. of  6 variables:
 $ Pond        : chr  "BVS" "BVS" "BVS" "BVS" ...
 $ Month       : chr  "January" "February" "March" "April" ...
 $ AvgTemp     : num  4.55 3.92 3.45 5.65 8.25 ...
 $ Year        : num  2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 ...
 $ Decade      : chr  "2020s" "2020s" "2020s" "2020s" ...
 $ diff_AvgTemp: num  -1.58 -1.59 -1.6 -1.65 -1.74 ...
# Filter out data for the reference year
DeltaMonthly_CRD45 <- combined_monthly_avg_with_diff %>%
  filter(Year != reference_year)

# Display the filtered data
print(DeltaMonthly_CRD45)
NA

Calculate mean differences

library(dplyr)

DeltaMonthly_CRD45

DiffMonthly_CRD45 <- DeltaMonthly_CRD45 %>%
  select(Pond, Month, Year, diff_AvgTemp)

# Create a new column based on year ranges
DiffMonthly_CRD45$Decade <- ifelse(DiffMonthly_CRD45$Year >= 2030 & DiffMonthly_CRD45$Year < 2040, "2030s",
                          ifelse(DiffMonthly_CRD45$Year >= 2060 & DiffMonthly_CRD45$Year < 2070, "2060s",
                          ifelse(DiffMonthly_CRD45$Year >= 2090 & DiffMonthly_CRD45$Year < 2100, "2090s",
                          "Other")))

# Print the updated data frame
print(DiffMonthly_CRD45)
  
# Convert Month to Date type
DiffMonthly_CRD45 <- DiffMonthly_CRD45 %>%
  mutate(Month = as.Date(paste0(Month, " 1 ", Year), format = "%B %d %Y"))

print(DiffMonthly_CRD45)

# Group by Pond and Month, then calculate mean and standard deviation of diff_AvgTemp
summary_stats <- DiffMonthly_CRD45 %>%
  dplyr::mutate(Month = format(Month, "%m")) %>%  # Extracts YYYY-MM format
  dplyr::group_by(Pond, Month, Decade) %>%
  dplyr::summarise(
    mean_diff_AvgTemp = mean(diff_AvgTemp, na.rm = TRUE),
    sd_diff_AvgTemp = sd(diff_AvgTemp, na.rm = TRUE)
  )
`summarise()` has grouped output by 'Pond', 'Month'. You can override using the `.groups` argument.
# View the summary statistics
print(summary_stats)

# Group by just Month, then calculate mean and standard deviation of diff_AvgTemp
summary_stats2 <- DiffMonthly_CRD45 %>%
  dplyr::mutate(Month = format(Month, "%m")) %>%  # Extracts YYYY-MM format
  dplyr::group_by(Month, Decade) %>%
  dplyr::summarise(
    mean_diff_AvgTemp = mean(diff_AvgTemp, na.rm = TRUE),
    sd_diff_AvgTemp = sd(diff_AvgTemp, na.rm = TRUE)
  )
`summarise()` has grouped output by 'Month'. You can override using the `.groups` argument.
# View the summary statistics
print(summary_stats2)

Plotting the monthly temperature change graphs

2030s

summary_stats # grouped by month and pond
summary_stats2 # grouped by just month

# 2. Monthly averages across ponds
MonthlyStats_2030 <- summary_stats2 %>%
  filter(Decade == "2030s") 

ggplot(data = MonthlyStats_2030, aes(x = Month)) +
  geom_point(aes(y = mean_diff_AvgTemp)) +
  theme_classic()


# Convert Month from character to numeric to ensure proper ordering in ggplot
MonthlyStats_2030$Month <- as.numeric(MonthlyStats_2030$Month)

# Plot using ggplot
MonthlyStats_2030Plot <- ggplot(data = MonthlyStats_2030, aes(x = Month)) +
  geom_line(aes(y = mean_diff_AvgTemp)) +  # Point plot with mean values
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +  # Horizontal dashed line at y = 0
  geom_ribbon(aes(ymin = mean_diff_AvgTemp - sd_diff_AvgTemp, ymax = mean_diff_AvgTemp + sd_diff_AvgTemp), fill = "blue", alpha = 0.3) +  # Ribbon for positive and negative error based on sd values
  scale_x_continuous(breaks = 1:12, labels = month.abb) +  # Adjust x-axis labels to show month abbreviations
  ylim(-4,6)+
  theme_classic() +
  labs(x = "", y = "Delta Temp (C)") +
  theme(axis.text.x = element_text(angle = 65, hjust = 1)) +
  theme(axis.title = element_text(size = 16),
        axis.text = element_text(size = 14))
MonthlyStats_2030Plot

2060s

# 2. Monthly averages across ponds
MonthlyStats_2060 <- summary_stats2 %>%
  filter(Decade == "2060s") 

ggplot(data = MonthlyStats_2060, aes(x = Month)) +
  geom_point(aes(y = mean_diff_AvgTemp)) +
  theme_classic()


# Convert Month from character to numeric to ensure proper ordering in ggplot
MonthlyStats_2060$Month <- as.numeric(MonthlyStats_2060$Month)

# Plot using ggplot
MonthlyStats_2060Plot <- ggplot(data = MonthlyStats_2060, aes(x = Month)) +
  geom_line(aes(y = mean_diff_AvgTemp)) +  # Point plot with mean values
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +  # Horizontal dashed line at y = 0
  geom_ribbon(aes(ymin = mean_diff_AvgTemp - sd_diff_AvgTemp, ymax = mean_diff_AvgTemp + sd_diff_AvgTemp), fill = "blue", alpha = 0.3) +  # Ribbon for positive and negative error based on sd values
  scale_x_continuous(breaks = 1:12, labels = month.abb) +  # Adjust x-axis labels to show month abbreviations
  ylim(-4,6)+
  theme_classic() +
  labs(x = "", y = "") +
  theme(axis.text.x = element_text(angle = 65, hjust = 1)) +
  theme(axis.title = element_text(size = 16),
        axis.text = element_text(size = 14))+
  theme(axis.text.y = element_blank(),  # Remove Y-axis tick mark labels
        axis.ticks.y = element_blank())
MonthlyStats_2060Plot

2090s

# 2. Monthly averages across ponds
MonthlyStats_2090 <- summary_stats2 %>%
  filter(Decade == "2090s") 

ggplot(data = MonthlyStats_2090, aes(x = Month)) +
  geom_point(aes(y = mean_diff_AvgTemp)) +
  theme_classic()


# Convert Month from character to numeric to ensure proper ordering in ggplot
MonthlyStats_2090$Month <- as.numeric(MonthlyStats_2090$Month)

# Plot using ggplot
MonthlyStats_2090Plot <- ggplot(data = MonthlyStats_2090, aes(x = Month)) +
  geom_line(aes(y = mean_diff_AvgTemp)) +  # Point plot with mean values
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +  # Horizontal dashed line at y = 0
  geom_ribbon(aes(ymin = mean_diff_AvgTemp - sd_diff_AvgTemp, ymax = mean_diff_AvgTemp + sd_diff_AvgTemp), fill = "blue", alpha = 0.3) +  # Ribbon for positive and negative error based on sd values
  scale_x_continuous(breaks = 1:12, labels = month.abb) +  # Adjust x-axis labels to show month abbreviations
  ylim(-4,6)+
  theme_classic() +
  theme(axis.text.x = element_text(angle = 65, hjust = 1)) +
  labs(x = "", y = "") +
  theme(axis.title = element_text(size = 16),
        axis.text = element_text(size = 14))+
  theme(axis.text.y = element_blank(),  # Remove Y-axis tick mark labels
        axis.ticks.y = element_blank())
MonthlyStats_2090Plot

Combine the plots together here for now

# Combine plots into a panel plot
DeltaMonth_CRD45_plot <- ggarrange(MonthlyStats_2030Plot, MonthlyStats_2060Plot, MonthlyStats_2090Plot, ncol = 3)

# Save the combined plot
ggsave("Corr_DeltaMonthCRD45.png", plot = DeltaMonth_CRD45_plot, width = 12, height = 3)

Create .csv files of the data for these graphs

write.csv(MonthlyStats_2030, file = "Corr_MonthlyStatsCRD45_2030.csv")
write.csv(MonthlyStats_2060, file = "Corr_MonthlyStatsCRD45_2060.csv")
write.csv(MonthlyStats_2090, file = "Corr_MonthlyStatsCRD45_2090.csv")
LS0tCnRpdGxlOiAiUG9uZCBUZW1wcyAtIERlbHRhIEdyYXBocyBhbmQgU2Vhc29uYWwgVHJlbmRzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tClRoaXMgaXMgY29kZSB1c2VkIHRvIG1ha2UgcGxvdHMgYmFzZWQgb24gb3V0cHV0IGZyb20gdGhlICJJbmRpdmlkdWFsUG9uZE1vZGVsc19Gb3JlY2FzdHM4NSIgZm9yIGJvdGh0aGUgQ1IgYW5kIFlGClJlYWQgaW4gdGhlIG91dHB1dCBmaWxlcyBmb3IgZWFjaCBwb25kL1JDUCBjb21iaW5hdGlvbiB0aGVuIHdvcmsgb24gZGVsdGEgZmlndXJlcyBhbmQgZmlndXJlcyBsaWtlIEhhbWxldCBldCBhbC4gMjAyMAoKYGBge3J9CnJtKGxpc3QgPSBscygpKQoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocmphZ3MpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShtYXRyaXhTdGF0cykKCnNldC5zZWVkKDEpCmBgYAoKU3RhcnRpbmcgd2l0aCB0aGUgQ29wcGVyIFJpdmVyIERlbHRhCgpSQ1AgNDUKCiMgUmVhZGluZyBpbiB0aGUgZGF0YQpgYGB7cn0KTW9kX0NSRDQ1IDwtIHJlYWQuY3N2KCJDb3JyX01vZF9DUkQ0NS5jc3YiLCBoZWFkZXIgPSBUKQpgYGAKCiAKIyMjIDIwMTItMjAyMApgYGB7cn0KIyBMaXN0IG9mIHVuaXF1ZSBwb25kIG5hbWVzIGZyb20gdGhlIGRhdGFmcmFtZQpwb25kX25hbWVzIDwtIHVuaXF1ZShNb2RfQ1JENDUkcG9uZF9uYW1lKQoKIyBJbml0aWFsaXplIGFuIGVtcHR5IGRhdGFmcmFtZSB0byBzdG9yZSByZXN1bHRzCmF2Z01lZF8yMDIwIDwtIGRhdGEuZnJhbWUoUG9uZCA9IHBvbmRfbmFtZXMsIEF2Z01lZF8yMDIwID0gbnVtZXJpYyhsZW5ndGgocG9uZF9uYW1lcykpKQoKIyBMb29wIHRocm91Z2ggZWFjaCBwb25kIG5hbWUKZm9yIChpIGluIHNlcV9hbG9uZyhwb25kX25hbWVzKSkgewogIHBvbmRfbmFtZSA8LSBwb25kX25hbWVzW2ldCiAgCiAgIyBGaWx0ZXIgZGF0YSBmb3IgdGhlIGN1cnJlbnQgcG9uZCBhbmQgZm9yIGRhdGVzIGJlZm9yZSBKYW51YXJ5IDEsIDIwMjEKICBmaWx0ZXJlZF9kYXRhIDwtIE1vZF9DUkQ0NSAlPiUKICAgIGZpbHRlcihwb25kX25hbWUgPT0gISFwb25kX25hbWUsIGFzLkRhdGUodGltZSkgPCBhcy5EYXRlKCIyMDIxLTAxLTAxIikpCiAgCiAgIyBDYWxjdWxhdGUgdGhlIG1lYW4gb2YgJ21lZCcgKHdoaWNoIGNvcnJlc3BvbmRzIHRvIFg1MCUpCiAgYXZnX21lZCA8LSBtZWFuKGZpbHRlcmVkX2RhdGEkbWVkLCBuYS5ybSA9IFRSVUUpCiAgCiAgIyBTdG9yZSB0aGUgcmVzdWx0IGluIHRoZSBkYXRhZnJhbWUKICBhdmdNZWRfMjAyMFtpLCAiQXZnTWVkXzIwMjAiXSA8LSBhdmdfbWVkCn0KCiMgUHJpbnQgdGhlIGRhdGFmcmFtZQpwcmludChhdmdNZWRfMjAyMCkKYGBgCgojIyMgMjAzMC0yMDM5CmBgYHtyfQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShnZ3Bsb3QyKQoKIyBMaXN0IG9mIHVuaXF1ZSBwb25kIG5hbWVzIGZyb20gdGhlIGRhdGFmcmFtZQpwb25kX25hbWVzIDwtIHVuaXF1ZShNb2RfQ1JENDUkcG9uZF9uYW1lKQoKIyBJbml0aWFsaXplIGEgZGF0YWZyYW1lIHRvIHN0b3JlIHJlc3VsdHMgd2l0aCB5ZWFycyBhcyBjb2x1bW5zCmF2Z01lZF8yMDMwIDwtIGRhdGEuZnJhbWUoUG9uZCA9IHBvbmRfbmFtZXMpCgojIExvb3AgdGhyb3VnaCBlYWNoIHllYXIgZnJvbSAyMDMwIHRvIDIwMzkKZm9yICh5ciBpbiAyMDMwOjIwMzkpIHsKICAjIENhbGN1bGF0ZSBhdmVyYWdlIG1lZGlhbnMgZm9yIGVhY2ggeWVhciBhbmQgc3RvcmUgYXMgYSBuZXcgY29sdW1uCiAgYXZnTWVkX2NvbCA8LSBzYXBwbHkocG9uZF9uYW1lcywgZnVuY3Rpb24ocG9uZF9uYW1lKSB7CiAgICB5ZWFybHlfZGF0YSA8LSBNb2RfQ1JENDUgJT4lCiAgICAgIGZpbHRlcihwb25kX25hbWUgPT0gISFwb25kX25hbWUsIHllYXIoYXMuRGF0ZSh0aW1lKSkgPT0geXIpCiAgICAKICAgIGF2Z19tZWQgPC0gbWVhbih5ZWFybHlfZGF0YSRtZWQsIG5hLnJtID0gVFJVRSkKICAgIHJldHVybihhdmdfbWVkKQogIH0pCiAgCiAgIyBBZGQgdGhlIHJlc3VsdHMgYXMgYSBuZXcgY29sdW1uIHRvIHRoZSBkYXRhZnJhbWUKICBhdmdNZWRfMjAzMFtbYXMuY2hhcmFjdGVyKHlyKV1dIDwtIGF2Z01lZF9jb2wKfQoKIyBQcmludCB0aGUgZmluYWwgZGF0YWZyYW1lCnByaW50KGF2Z01lZF8yMDMwKQoKIyBDb252ZXJ0IHRvIGxvbmcgZm9ybWF0IGZvciBnZ3Bsb3QyCmF2Z01lZF8yMDMwX2xvbmcgPC0gYXZnTWVkXzIwMzAgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtUG9uZCwgbmFtZXNfdG8gPSAiWWVhciIsIHZhbHVlc190byA9ICJBdmdNZWQiKQoKIyBQbG90IHRoZSBkYXRhCmdncGxvdChhdmdNZWRfMjAzMF9sb25nLCBhZXMoeCA9IFllYXIsIHkgPSBBdmdNZWQsIGNvbG9yID0gUG9uZCwgZ3JvdXAgPSBQb25kKSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KCkgKwogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBNZWRpYW4gcGVyIFBvbmQgZnJvbSAyMDMwIHRvIDIwMzkiLAogICAgICAgeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiQXZlcmFnZSBNZWRpYW4iKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKIyMjIDIwNjAtMjA2OQpgYGB7cn0KbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZ2dwbG90MikKCiMgTGlzdCBvZiB1bmlxdWUgcG9uZCBuYW1lcyBmcm9tIHRoZSBkYXRhZnJhbWUKcG9uZF9uYW1lcyA8LSB1bmlxdWUoTW9kX0NSRDQ1JHBvbmRfbmFtZSkKCiMgSW5pdGlhbGl6ZSBhIGRhdGFmcmFtZSB0byBzdG9yZSByZXN1bHRzIHdpdGggeWVhcnMgYXMgY29sdW1ucwphdmdNZWRfMjA2MCA8LSBkYXRhLmZyYW1lKFBvbmQgPSBwb25kX25hbWVzKQoKIyBMb29wIHRocm91Z2ggZWFjaCB5ZWFyIGZyb20gMjA2MCB0byAyMDY5CmZvciAoeXIgaW4gMjA2MDoyMDY5KSB7CiAgIyBDYWxjdWxhdGUgYXZlcmFnZSBtZWRpYW5zIGZvciBlYWNoIHllYXIgYW5kIHN0b3JlIGFzIGEgbmV3IGNvbHVtbgogIGF2Z01lZF9jb2wgPC0gc2FwcGx5KHBvbmRfbmFtZXMsIGZ1bmN0aW9uKHBvbmRfbmFtZSkgewogICAgeWVhcmx5X2RhdGEgPC0gTW9kX0NSRDQ1ICU+JQogICAgICBmaWx0ZXIocG9uZF9uYW1lID09ICEhcG9uZF9uYW1lLCB5ZWFyKGFzLkRhdGUodGltZSkpID09IHlyKQogICAgCiAgICBhdmdfbWVkIDwtIG1lYW4oeWVhcmx5X2RhdGEkbWVkLCBuYS5ybSA9IFRSVUUpCiAgICByZXR1cm4oYXZnX21lZCkKICB9KQogIAogICMgQWRkIHRoZSByZXN1bHRzIGFzIGEgbmV3IGNvbHVtbiB0byB0aGUgZGF0YWZyYW1lCiAgYXZnTWVkXzIwNjBbW2FzLmNoYXJhY3Rlcih5cildXSA8LSBhdmdNZWRfY29sCn0KCiMgUHJpbnQgdGhlIGZpbmFsIGRhdGFmcmFtZQpwcmludChhdmdNZWRfMjA2MCkKCiMgQ29udmVydCB0byBsb25nIGZvcm1hdCBmb3IgZ2dwbG90MgphdmdNZWRfMjA2MF9sb25nIDwtIGF2Z01lZF8yMDYwICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gLVBvbmQsIG5hbWVzX3RvID0gIlllYXIiLCB2YWx1ZXNfdG8gPSAiQXZnTWVkIikKCiMgUGxvdCB0aGUgZGF0YQpnZ3Bsb3QoYXZnTWVkXzIwNjBfbG9uZywgYWVzKHggPSBZZWFyLCB5ID0gQXZnTWVkLCBjb2xvciA9IFBvbmQsIGdyb3VwID0gUG9uZCkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9wb2ludCgpICsKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgTWVkaWFuIHBlciBQb25kIGZyb20gMjA2MCB0byAyMDY5IiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkF2ZXJhZ2UgTWVkaWFuIikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCiMjIyAyMDkwLTIwOTkKYGBge3J9CmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGdncGxvdDIpCgojIExpc3Qgb2YgdW5pcXVlIHBvbmQgbmFtZXMgZnJvbSB0aGUgZGF0YWZyYW1lCnBvbmRfbmFtZXMgPC0gdW5pcXVlKE1vZF9DUkQ0NSRwb25kX25hbWUpCgojIEluaXRpYWxpemUgYSBkYXRhZnJhbWUgdG8gc3RvcmUgcmVzdWx0cyB3aXRoIHllYXJzIGFzIGNvbHVtbnMKYXZnTWVkXzIwOTAgPC0gZGF0YS5mcmFtZShQb25kID0gcG9uZF9uYW1lcykKCiMgTG9vcCB0aHJvdWdoIGVhY2ggeWVhciBmcm9tIDIwOTAgdG8gMjA5OQpmb3IgKHlyIGluIDIwOTA6MjA5OSkgewogICMgQ2FsY3VsYXRlIGF2ZXJhZ2UgbWVkaWFucyBmb3IgZWFjaCB5ZWFyIGFuZCBzdG9yZSBhcyBhIG5ldyBjb2x1bW4KICBhdmdNZWRfY29sIDwtIHNhcHBseShwb25kX25hbWVzLCBmdW5jdGlvbihwb25kX25hbWUpIHsKICAgIHllYXJseV9kYXRhIDwtIE1vZF9DUkQ0NSAlPiUKICAgICAgZmlsdGVyKHBvbmRfbmFtZSA9PSAhIXBvbmRfbmFtZSwgeWVhcihhcy5EYXRlKHRpbWUpKSA9PSB5cikKICAgIAogICAgYXZnX21lZCA8LSBtZWFuKHllYXJseV9kYXRhJG1lZCwgbmEucm0gPSBUUlVFKQogICAgcmV0dXJuKGF2Z19tZWQpCiAgfSkKICAKICAjIEFkZCB0aGUgcmVzdWx0cyBhcyBhIG5ldyBjb2x1bW4gdG8gdGhlIGRhdGFmcmFtZQogIGF2Z01lZF8yMDkwW1thcy5jaGFyYWN0ZXIoeXIpXV0gPC0gYXZnTWVkX2NvbAp9CgojIFByaW50IHRoZSBmaW5hbCBkYXRhZnJhbWUKcHJpbnQoYXZnTWVkXzIwOTApCgojIENvbnZlcnQgdG8gbG9uZyBmb3JtYXQgZm9yIGdncGxvdDIKYXZnTWVkXzIwOTBfbG9uZyA8LSBhdmdNZWRfMjA5MCAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1Qb25kLCBuYW1lc190byA9ICJZZWFyIiwgdmFsdWVzX3RvID0gIkF2Z01lZCIpCgojIFBsb3QgdGhlIGRhdGEKZ2dwbG90KGF2Z01lZF8yMDkwX2xvbmcsIGFlcyh4ID0gWWVhciwgeSA9IEF2Z01lZCwgY29sb3IgPSBQb25kLCBncm91cCA9IFBvbmQpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIE1lZGlhbiBwZXIgUG9uZCBmcm9tIDIwOTAgdG8gMjA5OSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJBdmVyYWdlIE1lZGlhbiIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCmBgYHtyfQojIFJlbmFtZSBjb2x1bW5zIHRvIHJlZmxlY3Qgb25seSB0aGUgeWVhcnMKYXZnTWVkXzIwMjAgPC0gYXZnTWVkXzIwMjAgJT4lCiAgcmVuYW1lKEF2Z01lZF8yMDIwID0gQXZnTWVkXzIwMjApCgphdmdNZWRfMjAzMCA8LSBhdmdNZWRfMjAzMCAlPiUKICByZW5hbWUoYDIwMzBgID0gYDIwMzBgKQoKYXZnTWVkXzIwNjAgPC0gYXZnTWVkXzIwNjAgJT4lCiAgcmVuYW1lKGAyMDYwYCA9IGAyMDYwYCkKCmF2Z01lZF8yMDkwIDwtIGF2Z01lZF8yMDkwICU+JQogIHJlbmFtZShgMjA5MGAgPSBgMjA5MGApCgojIENvbWJpbmUgdGhlIGRhdGEgZnJhbWVzCmNvbWJpbmVkX2F2Z01lZCA8LSBhdmdNZWRfMjAyMCAlPiUKICBsZWZ0X2pvaW4oYXZnTWVkXzIwMzAsIGJ5ID0gIlBvbmQiKSAlPiUKICBsZWZ0X2pvaW4oYXZnTWVkXzIwNjAsIGJ5ID0gIlBvbmQiKSAlPiUKICBsZWZ0X2pvaW4oYXZnTWVkXzIwOTAsIGJ5ID0gIlBvbmQiKQoKIyBQcmludCB0aGUgZmluYWwgZGF0YWZyYW1lCnByaW50KGNvbWJpbmVkX2F2Z01lZCkKCiMgQ29udmVydCB0byBsb25nIGZvcm1hdCBmb3IgZ2dwbG90MiwgZXhjbHVkaW5nIEF2Z01lZF8yMDIwCmF2Z01lZF9sb25nIDwtIGNvbWJpbmVkX2F2Z01lZCAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1Qb25kLCBuYW1lc190byA9ICJZZWFyIiwgdmFsdWVzX3RvID0gIkF2Z01lZCIpICU+JQogIGZpbHRlcihZZWFyICVpbiUgYXMuY2hhcmFjdGVyKDIwMjE6MjE5OSkpCgojIFBsb3QgdGhlIGRhdGEKZ2dwbG90KGF2Z01lZF9sb25nLCBhZXMoeCA9IFllYXIsIHkgPSBBdmdNZWQsIGNvbG9yID0gUG9uZCwgZ3JvdXAgPSBQb25kKSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KCkgKwogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBNZWRpYW4gcGVyIFBvbmQgaW4gdGhlIENSRCAtIFJDUCA0LjUiLAogICAgICAgeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiQXZlcmFnZSBNZWRpYW4iKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpLCMgUm90YXRlIHgtYXhpcyBsYWJlbHMgYnkgNDUgZGVncmVlcwogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSAgCmBgYAoKCiMgQ2FsY3VhdGUgdGhlIGRpZmZlcmVuY2VzIGhlcmUgYXMgbmV3IGNvbHVtbnMgaW4gdGhlIGRhdGFmcmFtZQoKYGBge3J9CmxpYnJhcnkoZHBseXIpCgojIEFzc3VtaW5nIGNvbWJpbmVkX2F2Z01lZCBpcyBsb2FkZWQgYW5kIHN0cnVjdHVyZSB2ZXJpZmllZApEZWx0YV9jb21iaW5lZF9hdmdNZWQgPC0gY29tYmluZWRfYXZnTWVkICAjIFVzZSB5b3VyIGFjdHVhbCBkYXRhZnJhbWUKCiMgQ29sdW1ucyB0byBjYWxjdWxhdGUgZGlmZmVyZW5jZXMgZm9yCnllYXJzIDwtIGMoIjIwMzAiLCAiMjAzMSIsICIyMDMyIiwgIjIwMzMiLCAiMjAzNCIsIAogICAgICAgICAgICIyMDM1IiwgIjIwMzYiLCAiMjAzNyIsICIyMDM4IiwgIjIwMzkiLCAKICAgICAgICAgICAiMjA2MCIsICIyMDYxIiwgIjIwNjIiLCAiMjA2MyIsICIyMDY0IiwgCiAgICAgICAgICAgIjIwNjUiLCAiMjA2NiIsICIyMDY3IiwgIjIwNjgiLCAiMjA2OSIsIAogICAgICAgICAgICIyMDkwIiwgIjIwOTEiLCAiMjA5MiIsICIyMDkzIiwgIjIwOTQiLCAKICAgICAgICAgICAiMjA5NSIsICIyMDk2IiwgIjIwOTciLCAiMjA5OCIsICIyMDk5IikKCiMgTG9vcCB0aHJvdWdoIGVhY2ggeWVhciBhbmQgY2FsY3VsYXRlIHRoZSBkaWZmZXJlbmNlCmZvciAoeWVhciBpbiB5ZWFycykgewogICMgQ3JlYXRlIGEgbmV3IGNvbHVtbiBmb3IgdGhlIGRpZmZlcmVuY2UKICBkaWZmX2NvbF9uYW1lIDwtIHBhc3RlMCgiZGlmZl8iLCB5ZWFyKQogIERlbHRhX2NvbWJpbmVkX2F2Z01lZFtbZGlmZl9jb2xfbmFtZV1dIDwtIERlbHRhX2NvbWJpbmVkX2F2Z01lZFtbeWVhcl1dIC0gRGVsdGFfY29tYmluZWRfYXZnTWVkJGBBdmdNZWRfMjAyMGAKfQoKIyBEaXNwbGF5IHRoZSBzdHJ1Y3R1cmUgb2YgRGVsdGFfY29tYmluZWRfYXZnTWVkIHRvIHZlcmlmeQpzdHIoRGVsdGFfY29tYmluZWRfYXZnTWVkKQpgYGAKCmBgYHtyfQojIENyZWF0ZSBhIG5ldyBkYXRhZnJhbWUgd2l0aCB0aGUgY2FsY3VsYXRlZCBtZWFucyBhbmQgc3RhbmRhcmQgZGV2aWF0aW9ucwpEZWx0YV9DUkQ0NSA8LSBEZWx0YV9jb21iaW5lZF9hdmdNZWQgJT4lCiAgbXV0YXRlKAogICAgTWVhbl8yMDMwXzIwMzkgPSByb3dNZWFucyhzZWxlY3QoLiwgc3RhcnRzX3dpdGgoImRpZmZfMjAzIikpLCBuYS5ybSA9IFRSVUUpLCAgIyBDYWxjdWxhdGUgcm93LXdpc2UgbWVhbiBmb3IgY29sdW1ucyBzdGFydGluZyB3aXRoICJkaWZmXzIwMyIKICAgIFNEXzIwMzBfMjAzOSA9IHJvd1Nkcyhhcy5tYXRyaXgoc2VsZWN0KC4sIHN0YXJ0c193aXRoKCJkaWZmXzIwMyIpKSksIG5hLnJtID0gVFJVRSksICAjIENhbGN1bGF0ZSByb3ctd2lzZSBTRCBmb3IgY29sdW1ucyBzdGFydGluZyB3aXRoICJkaWZmXzIwMyIKICAgIE1lYW5fMjA2MF8yMDY5ID0gcm93TWVhbnMoc2VsZWN0KC4sIHN0YXJ0c193aXRoKCJkaWZmXzIwNiIpKSwgbmEucm0gPSBUUlVFKSwgICMgQ2FsY3VsYXRlIHJvdy13aXNlIG1lYW4gZm9yIGNvbHVtbnMgc3RhcnRpbmcgd2l0aCAiZGlmZl8yMDYiCiAgICBTRF8yMDYwXzIwNjkgPSByb3dTZHMoYXMubWF0cml4KHNlbGVjdCguLCBzdGFydHNfd2l0aCgiZGlmZl8yMDYiKSkpLCBuYS5ybSA9IFRSVUUpLCAgIyBDYWxjdWxhdGUgcm93LXdpc2UgU0QgZm9yIGNvbHVtbnMgc3RhcnRpbmcgd2l0aCAiZGlmZl8yMDYiCiAgICBNZWFuXzIwOTBfMjA5OSA9IHJvd01lYW5zKHNlbGVjdCguLCBzdGFydHNfd2l0aCgiZGlmZl8yMDkiKSksIG5hLnJtID0gVFJVRSksICAjIENhbGN1bGF0ZSByb3ctd2lzZSBtZWFuIGZvciBjb2x1bW5zIHN0YXJ0aW5nIHdpdGggImRpZmZfMjA5IgogICAgU0RfMjA5MF8yMDk5ID0gcm93U2RzKGFzLm1hdHJpeChzZWxlY3QoLiwgc3RhcnRzX3dpdGgoImRpZmZfMjA5IikpKSwgbmEucm0gPSBUUlVFKSAgIyBDYWxjdWxhdGUgcm93LXdpc2UgU0QgZm9yIGNvbHVtbnMgc3RhcnRpbmcgd2l0aCAiZGlmZl8yMDkiCiAgKQoKIyBQcmludCB0aGUgc3RydWN0dXJlIG9mIHRoZSBuZXcgZGF0YWZyYW1lCnN0cihEZWx0YV9DUkQ0NSkKCiMgT3B0aW9uYWxseSwgdmlldyB0aGUgZmlyc3QgZmV3IHJvd3MgdG8gY2hlY2sgdGhlIG5ldyBjb2x1bW5zCmhlYWQoRGVsdGFfQ1JENDUpCmBgYAoKIyMgUHV0IHRoZXNlIGludG8gdG90YWwgbWVhbi9zdGFuZGFyZCBkZXZpYXRpb25zCgpgYGB7cn0KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMKbGlicmFyeShkcGx5cikKCiMgU2VsZWN0IGFuZCByZW5hbWUgY29sdW1ucyBmcm9tIERlbHRhX0NSRDQ1CkNSRDQ1X2RlY2FkYWwgPC0gRGVsdGFfQ1JENDUgJT4lCiAgc2VsZWN0KFBvbmQsIHN0YXJ0c193aXRoKCJNZWFuXyIpLCBzdGFydHNfd2l0aCgiU0RfIikpCgojIFJlbmFtZSBjb2x1bW5zIHdpdGhvdXQgdGhlICdZJyBwcmVmaXggZm9yIG1lYW5zCm5hbWVzKENSRDQ1X2RlY2FkYWwpIDwtIHN1YigiXk1lYW5fIiwgIk1lYW5fIiwgbmFtZXMoQ1JENDVfZGVjYWRhbCkpCgojIFJlbmFtZSBjb2x1bW5zIHdpdGhvdXQgdGhlICdZJyBwcmVmaXggZm9yIHN0YW5kYXJkIGRldmlhdGlvbnMKbmFtZXMoQ1JENDVfZGVjYWRhbCkgPC0gc3ViKCJeU0RfIiwgIlNEXyIsIG5hbWVzKENSRDQ1X2RlY2FkYWwpKQoKIyBQcmludCB0aGUgc3RydWN0dXJlIG9mIHRoZSB1cGRhdGVkIGRhdGFmcmFtZQpzdHIoQ1JENDVfZGVjYWRhbCkKCiMgT3B0aW9uYWxseSwgdmlldyB0aGUgZmlyc3QgZmV3IHJvd3MgdG8gY2hlY2sgdGhlIG5ldyBjb2x1bW5zCmhlYWQoQ1JENDVfZGVjYWRhbCkKYGBgCgojIE1ha2luZyB0aGUgcGxvdHMgb2YgdGhlc2UgZGVsdGFzCmBgYHtyfQojIExvYWQgcmVxdWlyZWQgcGFja2FnZXMKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShnZ3B1YnIpCgojIENyZWF0ZSBhIGdyb3VwZWQgYmFyIHBsb3Qgd2l0aCBlcnJvciBiYXJzIGZvciBNZWFuIDIwMzAKcGxvdF8yMDMwIDwtIGdncGxvdChDUkQ0NV9kZWNhZGFsLCBhZXMoeCA9IFBvbmQsIHkgPSBNZWFuXzIwMzBfMjAzOSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICIjRkZEOTJGIiwgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IE1lYW5fMjAzMF8yMDM5IC0gU0RfMjAzMF8yMDM5LCB5bWF4ID0gTWVhbl8yMDMwXzIwMzkgKyBTRF8yMDMwXzIwMzkpLAogICAgICAgICAgICAgICAgd2lkdGggPSAwLjQsICAjIEFkanVzdCB0aGUgd2lkdGggb2YgZXJyb3IgYmFycyBhcyBuZWVkZWQKICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpKSArCiAgbGFicyh4ID0gIiIsIHkgPSAiRGVsdGEgVGVtcCAoQykiKSArCiAgeWxpbSgtMSwgNSkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSAgIyBDZW50ZXJlZCB0aXRsZQpwbG90XzIwMzAKCiMgQ3JlYXRlIGEgZ3JvdXBlZCBiYXIgcGxvdCB3aXRoIGVycm9yIGJhcnMgZm9yIE1lYW4gMjA2MApwbG90XzIwNjAgPC0gZ2dwbG90KENSRDQ1X2RlY2FkYWwsIGFlcyh4ID0gUG9uZCwgeSA9IE1lYW5fMjA2MF8yMDY5KSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiNGNDZENDMiLCBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbl8yMDYwXzIwNjkgLSBTRF8yMDYwXzIwNjksIHltYXggPSBNZWFuXzIwNjBfMjA2OSArIFNEXzIwNjBfMjA2OSksCiAgICAgICAgICAgICAgICB3aWR0aCA9IDAuNCwgICMgQWRqdXN0IHRoZSB3aWR0aCBvZiBlcnJvciBiYXJzIGFzIG5lZWRlZAogICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSkpICsKICBsYWJzKHggPSAiIiwgeSA9ICIiKSArICAjIE5vIHktYXhpcyBsYWJlbAogIHlsaW0oLTEsIDUpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKyAgIyBDZW50ZXJlZCB0aXRsZSAKICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICMgUmVtb3ZlIFktYXhpcyB0aWNrIG1hcmsgbGFiZWxzCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpKSAgICMgUmVtb3ZlIFktYXhpcyB0aWNrcwpwbG90XzIwNjAKCiMgQ3JlYXRlIGEgZ3JvdXBlZCBiYXIgcGxvdCB3aXRoIGVycm9yIGJhcnMgZm9yIE1lYW4gMjA5MApwbG90XzIwOTAgPC0gZ2dwbG90KENSRDQ1X2RlY2FkYWwsIGFlcyh4ID0gUG9uZCwgeSA9IE1lYW5fMjA5MF8yMDk5KSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiNENzMwMjciLCBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbl8yMDkwXzIwOTkgLSBTRF8yMDkwXzIwOTksIHltYXggPSBNZWFuXzIwOTBfMjA5OSArIFNEXzIwOTBfMjA5OSksCiAgICAgICAgICAgICAgICB3aWR0aCA9IDAuNCwgICMgQWRqdXN0IHRoZSB3aWR0aCBvZiBlcnJvciBiYXJzIGFzIG5lZWRlZAogICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSkpICsKICBsYWJzKHggPSAiIiwgeSA9ICIiKSArICAjIE5vIHktYXhpcyBsYWJlbAogIHlsaW0oLTEsIDUpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKyAgIyBDZW50ZXJlZCB0aXRsZSAKICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICMgUmVtb3ZlIFktYXhpcyB0aWNrIG1hcmsgbGFiZWxzCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpKSAgICMgUmVtb3ZlIFktYXhpcyB0aWNrcwpwbG90XzIwOTAKCiMgQ29tYmluZSBwbG90cyBpbnRvIGEgcGFuZWwgcGxvdApEZWx0YV9DUkQ0NV9wbG90IDwtIGdnYXJyYW5nZShwbG90XzIwMzAsIHBsb3RfMjA2MCwgcGxvdF8yMDkwLCBuY29sID0gMykKCiMgU2F2ZSB0aGUgY29tYmluZWQgcGxvdApnZ3NhdmUoIkNvcnJfRGVsdGFDUkQ0NS5wbmciLCBwbG90ID0gRGVsdGFfQ1JENDVfcGxvdCwgd2lkdGggPSA4LCBoZWlnaHQgPSAzKQpgYGAKCiMgU3RhdGlzdGljYWwgdGVzdHMgZm9yIGVhY2ggb2YgdGhlc2UgcG9uZHMgZm9yIDIwMzBzLCAyMDYwcywgYW5kIDIwOTBzCgojIyMgMjAzMHMKYGBge3J9CkRlbHRhX0NSRDQ1CgojIExvYWQgcmVxdWlyZWQgbGlicmFyaWVzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkodGlkeXIpCgojIFN0ZXAgMTogUHJlcGFyZSB0aGUgZGF0YQpkYXRhX2xvbmcgPC0gRGVsdGFfQ1JENDUgJT4lCiAgc2VsZWN0KFBvbmQsIG1hdGNoZXMoIl5kaWZmXzIwM1swLTldJCIpKSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1Qb25kLCBuYW1lc190byA9ICJZZWFyIiwgdmFsdWVzX3RvID0gIkRpZmZlcmVuY2UiKQoKYm94cGxvdChkYXRhX2xvbmckRGlmZmVyZW5jZSB+IGRhdGFfbG9uZyRQb25kKQoKIyBTdGVwIDI6IENvbmR1Y3QgQU5PVkEgYnkgZ3JvdXBpbmcgYnkgUG9uZApyZXNfQ1JENDUgPC0gYW92KERpZmZlcmVuY2UgfiBQb25kLCBkYXRhID0gZGF0YV9sb25nKQpzdW1tYXJ5KHJlc19DUkQ0NSkKCiMgU3RlcCAzOiBUdWtleSBIU0QKcG9zdF90ZXN0X0NSRDQ1IDwtIFR1a2V5SFNEKHJlc19DUkQ0NSkKcG9zdF90ZXN0X0NSRDQ1CgpgYGAKCiMjIyAyMDYwcwpgYGB7cn0KRGVsdGFfQ1JENDUKCiMgTG9hZCByZXF1aXJlZCBsaWJyYXJpZXMKbGlicmFyeShkcGx5cikKbGlicmFyeShicm9vbSkKCiMgU3RlcCAxOiBQcmVwYXJlIHRoZSBkYXRhCmRhdGFfbG9uZyA8LSBEZWx0YV9DUkQ0NSAlPiUKICBzZWxlY3QoUG9uZCwgbWF0Y2hlcygiXmRpZmZfMjA2WzAtOV0kIikpICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gLVBvbmQsIG5hbWVzX3RvID0gIlllYXIiLCB2YWx1ZXNfdG8gPSAiRGlmZmVyZW5jZSIpCgpib3hwbG90KGRhdGFfbG9uZyREaWZmZXJlbmNlIH4gZGF0YV9sb25nJFBvbmQpCgojIFN0ZXAgMjogQ29uZHVjdCBBTk9WQSBieSBncm91cGluZyBieSBQb25kCnJlc19DUkQ0NSA8LSBhb3YoRGlmZmVyZW5jZSB+IFBvbmQsIGRhdGEgPSBkYXRhX2xvbmcpCnN1bW1hcnkocmVzX0NSRDQ1KQoKIyBTdGVwIDM6IFR1a2V5IEhTRApwb3N0X3Rlc3RfQ1JENDUgPC0gVHVrZXlIU0QocmVzX0NSRDQ1KQpwb3N0X3Rlc3RfQ1JENDUKYGBgCgojIyMgMjA5MHMKYGBge3J9CkRlbHRhX0NSRDQ1CgojIExvYWQgcmVxdWlyZWQgbGlicmFyaWVzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoYnJvb20pCgojIFN0ZXAgMTogUHJlcGFyZSB0aGUgZGF0YQpkYXRhX2xvbmcgPC0gRGVsdGFfQ1JENDUgJT4lCiAgc2VsZWN0KFBvbmQsIG1hdGNoZXMoIl5kaWZmXzIwOVswLTldJCIpKSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1Qb25kLCBuYW1lc190byA9ICJZZWFyIiwgdmFsdWVzX3RvID0gIkRpZmZlcmVuY2UiKQoKYm94cGxvdChkYXRhX2xvbmckRGlmZmVyZW5jZSB+IGRhdGFfbG9uZyRQb25kKQoKIyBTdGVwIDI6IENvbmR1Y3QgQU5PVkEgYnkgZ3JvdXBpbmcgYnkgUG9uZApyZXNfQ1JENDUgPC0gYW92KERpZmZlcmVuY2UgfiBQb25kLCBkYXRhID0gZGF0YV9sb25nKQpzdW1tYXJ5KHJlc19DUkQ0NSkKCiMgU3RlcCAzOiBUdWtleSBIU0QKcG9zdF90ZXN0X0NSRDQ1IDwtIFR1a2V5SFNEKHJlc19DUkQ0NSkKcG9zdF90ZXN0X0NSRDQ1CmBgYAoKIyBNYWtpbmcgcGxvdHMgb2YgZXJyb3IgYnkgc2Vhc29uCgojIyAyMDEyLTIwMjAKYGBge3J9CiMgRXh0cmFjdCB1bmlxdWUgcG9uZCBuYW1lcyBmcm9tIHRoZSBkYXRhZnJhbWUKc2hvcnRfbmFtZXMgPC0gdW5pcXVlKE1vZF9DUkQ0NSRwb25kX25hbWUpCgojIEluaXRpYWxpemUgYW4gZW1wdHkgZGF0YWZyYW1lIHRvIHN0b3JlIG1vbnRobHkgbWVhbiByZXN1bHRzCm1vbnRobHlfbWVhbnMgPC0gZGF0YS5mcmFtZShQb25kID0gY2hhcmFjdGVyKCksIE1vbnRoID0gY2hhcmFjdGVyKCksIEF2Z1RlbXAgPSBudW1lcmljKCksIFllYXIgPSBudW1lcmljKCksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKCiMgQ29udmVydCAndGltZScgY29sdW1uIHRvIERhdGUgY2xhc3MKTW9kX0NSRDQ1JHRpbWUgPC0gYXMuRGF0ZShNb2RfQ1JENDUkdGltZSwgZm9ybWF0PSIlWS0lbS0lZCIpCgojIEV4dHJhY3QgeWVhciBhbmQgbW9udGggZnJvbSAndGltZScgY29sdW1uCk1vZF9DUkQ0NSRZZWFyIDwtIGZvcm1hdChNb2RfQ1JENDUkdGltZSwgIiVZIikKTW9kX0NSRDQ1JE1vbnRoIDwtIGZvcm1hdChNb2RfQ1JENDUkdGltZSwgIiVCIikKCiMgTG9vcCB0aHJvdWdoIGVhY2ggdW5pcXVlIHBvbmQgbmFtZQpmb3IgKHNob3J0X25hbWUgaW4gc2hvcnRfbmFtZXMpIHsKICAjIEZpbHRlciBkYXRhIGZvciB0aGUgY3VycmVudCBwb25kCiAgcG9uZF9kYXRhIDwtIHN1YnNldChNb2RfQ1JENDUsIHBvbmRfbmFtZSA9PSBzaG9ydF9uYW1lKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggbW9udGgKICBmb3IgKG1vbnRoIGluIG1vbnRoLm5hbWUpIHsKICAgICMgRmlsdGVyIGRhdGEgZm9yIHRoZSBjdXJyZW50IG1vbnRoCiAgICBmaWx0ZXJlZF9kYXRhIDwtIHN1YnNldChwb25kX2RhdGEsIE1vbnRoID09IG1vbnRoKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgbWVhbiBvZiAnbWVkJyBmb3IgdGhlIGN1cnJlbnQgbW9udGgKICAgIGF2Z19tZWQgPC0gbWVhbihmaWx0ZXJlZF9kYXRhJG1lZCwgbmEucm0gPSBUUlVFKQogICAgCiAgICAjIEFwcGVuZCByZXN1bHRzIHRvIG1vbnRobHlfbWVhbnMgZGF0YWZyYW1lCiAgICBtb250aGx5X21lYW5zIDwtIHJiaW5kKG1vbnRobHlfbWVhbnMsIGRhdGEuZnJhbWUoUG9uZCA9IHNob3J0X25hbWUsIE1vbnRoID0gbW9udGgsIEF2Z1RlbXAgPSBhdmdfbWVkLCBZZWFyID0gMjAyMCkpCiAgfQp9CgojIFByaW50IHRoZSBtb250aGx5IG1lYW5zIGRhdGFmcmFtZQpwcmludChtb250aGx5X21lYW5zKQoKIyBQbG90dGluZyB0aGUgZGF0YQpnZ3Bsb3QobW9udGhseV9tZWFucywgYWVzKHggPSBNb250aCwgeSA9IEF2Z1RlbXAsIGNvbG9yID0gUG9uZCwgZ3JvdXAgPSBQb25kKSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gbW9udGgubmFtZSkgKwogIGxhYnModGl0bGUgPSAiTW9udGhseSBBdmVyYWdlIFRlbXBlcmF0dXJlcyBmb3IgRWFjaCBQb25kIiwKICAgICAgIHggPSAiTW9udGgiLAogICAgICAgeSA9ICJBdmVyYWdlIFRlbXBlcmF0dXJlIiwKICAgICAgIGNvbG9yID0gIlBvbmQiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKCiMjIDIwMzAsIDIwNjAsIGFuZCAyMDkwCmBgYHtyfQojIERlZmluZSB0aGUgY29ycmVjdCBvcmRlciBmb3IgbW9udGhzCm1vbnRoX29yZGVyIDwtIGMoIkphbnVhcnkiLCAiRmVicnVhcnkiLCAiTWFyY2giLCAiQXByaWwiLCAiTWF5IiwgIkp1bmUiLCAKICAgICAgICAgICAgICAgICAgIkp1bHkiLCAiQXVndXN0IiwgIlNlcHRlbWJlciIsICJPY3RvYmVyIiwgIk5vdmVtYmVyIiwgIkRlY2VtYmVyIikKCiMgUmVjYWxjdWxhdGUgbW9udGhseSBhdmVyYWdlcyB3aXRoIGNvcnJlY3QgbW9udGggb3JkZXJpbmcKY2FsY3VsYXRlX21vbnRobHlfYXZlcmFnZXMgPC0gZnVuY3Rpb24oZGF0YSwgZGVjYWRlX3N0YXJ0LCBkZWNhZGVfZW5kKSB7CiAgIyBJbml0aWFsaXplIGVtcHR5IGRhdGFmcmFtZSB0byBzdG9yZSBtb250aGx5IGF2ZXJhZ2VzCiAgbW9udGhseV9hdmdfdGFibGUgPC0gZGF0YS5mcmFtZShQb25kID0gY2hhcmFjdGVyKCksIE1vbnRoID0gZmFjdG9yKCksIEF2Z1RlbXAgPSBudW1lcmljKCksIFllYXIgPSBpbnRlZ2VyKCksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHllYXIgaW4gdGhlIGRlY2FkZQogIGZvciAoeXIgaW4gZGVjYWRlX3N0YXJ0OmRlY2FkZV9lbmQpIHsKICAgICMgRmlsdGVyIGRhdGEgZm9yIHRoZSBjdXJyZW50IHllYXIKICAgIHllYXJseV9kYXRhIDwtIGRhdGEgJT4lCiAgICAgIGZpbHRlcih5ZWFyKHRpbWUpID09IHlyKQogICAgCiAgICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvbmQKICAgIGZvciAocG9uZF9uYW1lIGluIHVuaXF1ZShkYXRhJHBvbmRfbmFtZSkpIHsKICAgICAgcG9uZF9kYXRhIDwtIHllYXJseV9kYXRhICU+JQogICAgICAgIGZpbHRlcihwb25kX25hbWUgPT0gcG9uZF9uYW1lKQogICAgICAKICAgICAgIyBMb29wIHRocm91Z2ggZWFjaCBtb250aAogICAgICBmb3IgKG1vbnRoIGluIG1vbnRoX29yZGVyKSB7CiAgICAgICAgIyBGaWx0ZXIgZGF0YSBmb3IgdGhlIGN1cnJlbnQgbW9udGgKICAgICAgICBtb250aGx5X2RhdGEgPC0gcG9uZF9kYXRhICU+JQogICAgICAgICAgZmlsdGVyKGZvcm1hdCh0aW1lLCAiJUIiKSA9PSBtb250aCkKICAgICAgICAKICAgICAgICAjIENhbGN1bGF0ZSB0aGUgbWVhbiBvZiAnbWVkJyBmb3IgdGhlIGN1cnJlbnQgbW9udGgKICAgICAgICBhdmdfdGVtcCA8LSBtZWFuKG1vbnRobHlfZGF0YSRtZWQsIG5hLnJtID0gVFJVRSkKICAgICAgICAKICAgICAgICAjIEFwcGVuZCByZXN1bHRzIHRvIG1vbnRobHlfYXZnX3RhYmxlIGRhdGFmcmFtZQogICAgICAgIG1vbnRobHlfYXZnX3RhYmxlIDwtIHJiaW5kKG1vbnRobHlfYXZnX3RhYmxlLCBkYXRhLmZyYW1lKFBvbmQgPSBwb25kX25hbWUsIE1vbnRoID0gZmFjdG9yKG1vbnRoLCBsZXZlbHMgPSBtb250aF9vcmRlciksIEF2Z1RlbXAgPSBhdmdfdGVtcCwgWWVhciA9IHlyKSkKICAgICAgfQogICAgfQogIH0KICAKICByZXR1cm4obW9udGhseV9hdmdfdGFibGUpCn0KCiMgQ2FsY3VsYXRlIG1vbnRobHkgYXZlcmFnZXMgZm9yIGVhY2ggZGVjYWRlCm1vbnRobHlfYXZnWDUwX3RhYmxlXzIwMzBzIDwtIGNhbGN1bGF0ZV9tb250aGx5X2F2ZXJhZ2VzKE1vZF9DUkQ0NSwgMjAzMCwgMjAzOSkKbW9udGhseV9hdmdYNTBfdGFibGVfMjA2MHMgPC0gY2FsY3VsYXRlX21vbnRobHlfYXZlcmFnZXMoTW9kX0NSRDQ1LCAyMDYwLCAyMDY5KQptb250aGx5X2F2Z1g1MF90YWJsZV8yMDkwcyA8LSBjYWxjdWxhdGVfbW9udGhseV9hdmVyYWdlcyhNb2RfQ1JENDUsIDIwOTAsIDIwOTkpCmBgYAojIENvbWJpbmUgYWxsIHRoZSBtb250aGx5IGF2ZXJhZ2UgdGFibGVzIGludG8gb25lIGRhdGFmcmFtZSAKCmBgYHtyfQojIEFkZCBhIERlY2FkZSBjb2x1bW4gdG8gZWFjaCBkYXRhZnJhbWUKbW9udGhseV9tZWFucyA8LSBtb250aGx5X21lYW5zICU+JQogIG11dGF0ZShEZWNhZGUgPSAiMjAyMHMiKQoKbW9udGhseV9hdmdYNTBfdGFibGVfMjAzMHMgPC0gbW9udGhseV9hdmdYNTBfdGFibGVfMjAzMHMgJT4lCiAgbXV0YXRlKERlY2FkZSA9ICIyMDMwcyIpCgptb250aGx5X2F2Z1g1MF90YWJsZV8yMDYwcyA8LSBtb250aGx5X2F2Z1g1MF90YWJsZV8yMDYwcyAlPiUKICBtdXRhdGUoRGVjYWRlID0gIjIwNjBzIikKCm1vbnRobHlfYXZnWDUwX3RhYmxlXzIwOTBzIDwtIG1vbnRobHlfYXZnWDUwX3RhYmxlXzIwOTBzICU+JQogIG11dGF0ZShEZWNhZGUgPSAiMjA5MHMiKQoKIyBDb21iaW5lIGFsbCBtb250aGx5IGF2ZXJhZ2UgdGFibGVzIGludG8gb25lIGRhdGFmcmFtZQpjb21iaW5lZF9tb250aGx5X2F2ZyA8LSBiaW5kX3Jvd3MoCiAgbW9udGhseV9tZWFucywKICBtb250aGx5X2F2Z1g1MF90YWJsZV8yMDMwcywKICBtb250aGx5X2F2Z1g1MF90YWJsZV8yMDYwcywKICBtb250aGx5X2F2Z1g1MF90YWJsZV8yMDkwcwopCgojIFByaW50IHRoZSBjb21iaW5lZCBkYXRhZnJhbWUKcHJpbnQoY29tYmluZWRfbW9udGhseV9hdmcpCmBgYAoKIyBDYWxjdWxhdGUgdGhlIGRpZmZlcmVuY2VzIGhlcmUgYXMgY29tcGFyZWQgdG8gMjAyMApgYGB7cn0KIyBEZWZpbmUgdGhlIHJlZmVyZW5jZSB5ZWFyCnJlZmVyZW5jZV95ZWFyIDwtIDIwMjAKCiMgQ2hlY2sgaWYgdGhlIGNvbHVtbiBleGlzdHMgYW5kIGlzIGNvcnJlY3RseSBwb3B1bGF0ZWQKc3VtbWFyeShjb21iaW5lZF9tb250aGx5X2F2ZykKCiMgQ2FsY3VsYXRlIGF2ZXJhZ2UgdGVtcGVyYXR1cmUgZm9yIGVhY2ggbW9udGggaW4gdGhlIHJlZmVyZW5jZSB5ZWFyCnJlZl95ZWFyX2F2ZyA8LSBjb21iaW5lZF9tb250aGx5X2F2ZyAlPiUKICBmaWx0ZXIoWWVhciA9PSByZWZlcmVuY2VfeWVhcikgJT4lCiAgZ3JvdXBfYnkoTW9udGgpICU+JQogIHN1bW1hcmlzZShhdmdfdGVtcF9yZWZfeWVhciA9IG1lYW4oQXZnVGVtcCwgbmEucm0gPSBUUlVFKSkKCiMgSm9pbiByZWZlcmVuY2UgeWVhciBhdmVyYWdlcyB3aXRoIHRoZSBtYWluIGRhdGFzZXQKY29tYmluZWRfbW9udGhseV9hdmdfd2l0aF9kaWZmIDwtIGNvbWJpbmVkX21vbnRobHlfYXZnICU+JQogIGxlZnRfam9pbihyZWZfeWVhcl9hdmcsIGJ5ID0gIk1vbnRoIikgJT4lCiAgbXV0YXRlKGRpZmZfQXZnVGVtcCA9IEF2Z1RlbXAgLSBhdmdfdGVtcF9yZWZfeWVhcikgJT4lCiAgc2VsZWN0KC1hdmdfdGVtcF9yZWZfeWVhcikgICMgUmVtb3ZlIHRoZSByZWZlcmVuY2UgeWVhciBhdmVyYWdlIGNvbHVtbgoKIyBEaXNwbGF5IHRoZSBzdHJ1Y3R1cmUgdG8gdmVyaWZ5CnN0cihjb21iaW5lZF9tb250aGx5X2F2Z193aXRoX2RpZmYpCgojIEZpbHRlciBvdXQgZGF0YSBmb3IgdGhlIHJlZmVyZW5jZSB5ZWFyCkRlbHRhTW9udGhseV9DUkQ0NSA8LSBjb21iaW5lZF9tb250aGx5X2F2Z193aXRoX2RpZmYgJT4lCiAgZmlsdGVyKFllYXIgIT0gcmVmZXJlbmNlX3llYXIpCgojIERpc3BsYXkgdGhlIGZpbHRlcmVkIGRhdGEKcHJpbnQoRGVsdGFNb250aGx5X0NSRDQ1KQoKYGBgCgoKIyBDYWxjdWxhdGUgbWVhbiBkaWZmZXJlbmNlcwoKYGBge3J9CmxpYnJhcnkoZHBseXIpCgpEZWx0YU1vbnRobHlfQ1JENDUKCkRpZmZNb250aGx5X0NSRDQ1IDwtIERlbHRhTW9udGhseV9DUkQ0NSAlPiUKICBzZWxlY3QoUG9uZCwgTW9udGgsIFllYXIsIGRpZmZfQXZnVGVtcCkKCiMgQ3JlYXRlIGEgbmV3IGNvbHVtbiBiYXNlZCBvbiB5ZWFyIHJhbmdlcwpEaWZmTW9udGhseV9DUkQ0NSREZWNhZGUgPC0gaWZlbHNlKERpZmZNb250aGx5X0NSRDQ1JFllYXIgPj0gMjAzMCAmIERpZmZNb250aGx5X0NSRDQ1JFllYXIgPCAyMDQwLCAiMjAzMHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEaWZmTW9udGhseV9DUkQ0NSRZZWFyID49IDIwNjAgJiBEaWZmTW9udGhseV9DUkQ0NSRZZWFyIDwgMjA3MCwgIjIwNjBzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGlmZk1vbnRobHlfQ1JENDUkWWVhciA+PSAyMDkwICYgRGlmZk1vbnRobHlfQ1JENDUkWWVhciA8IDIxMDAsICIyMDkwcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIk90aGVyIikpKQoKIyBQcmludCB0aGUgdXBkYXRlZCBkYXRhIGZyYW1lCnByaW50KERpZmZNb250aGx5X0NSRDQ1KQogIAojIENvbnZlcnQgTW9udGggdG8gRGF0ZSB0eXBlCkRpZmZNb250aGx5X0NSRDQ1IDwtIERpZmZNb250aGx5X0NSRDQ1ICU+JQogIG11dGF0ZShNb250aCA9IGFzLkRhdGUocGFzdGUwKE1vbnRoLCAiIDEgIiwgWWVhciksIGZvcm1hdCA9ICIlQiAlZCAlWSIpKQoKcHJpbnQoRGlmZk1vbnRobHlfQ1JENDUpCgojIEdyb3VwIGJ5IFBvbmQgYW5kIE1vbnRoLCB0aGVuIGNhbGN1bGF0ZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2YgZGlmZl9BdmdUZW1wCnN1bW1hcnlfc3RhdHMgPC0gRGlmZk1vbnRobHlfQ1JENDUgJT4lCiAgZHBseXI6Om11dGF0ZShNb250aCA9IGZvcm1hdChNb250aCwgIiVtIikpICU+JSAgIyBFeHRyYWN0cyBZWVlZLU1NIGZvcm1hdAogIGRwbHlyOjpncm91cF9ieShQb25kLCBNb250aCwgRGVjYWRlKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKAogICAgbWVhbl9kaWZmX0F2Z1RlbXAgPSBtZWFuKGRpZmZfQXZnVGVtcCwgbmEucm0gPSBUUlVFKSwKICAgIHNkX2RpZmZfQXZnVGVtcCA9IHNkKGRpZmZfQXZnVGVtcCwgbmEucm0gPSBUUlVFKQogICkKCiMgVmlldyB0aGUgc3VtbWFyeSBzdGF0aXN0aWNzCnByaW50KHN1bW1hcnlfc3RhdHMpCgojIEdyb3VwIGJ5IGp1c3QgTW9udGgsIHRoZW4gY2FsY3VsYXRlIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBkaWZmX0F2Z1RlbXAKc3VtbWFyeV9zdGF0czIgPC0gRGlmZk1vbnRobHlfQ1JENDUgJT4lCiAgZHBseXI6Om11dGF0ZShNb250aCA9IGZvcm1hdChNb250aCwgIiVtIikpICU+JSAgIyBFeHRyYWN0cyBZWVlZLU1NIGZvcm1hdAogIGRwbHlyOjpncm91cF9ieShNb250aCwgRGVjYWRlKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKAogICAgbWVhbl9kaWZmX0F2Z1RlbXAgPSBtZWFuKGRpZmZfQXZnVGVtcCwgbmEucm0gPSBUUlVFKSwKICAgIHNkX2RpZmZfQXZnVGVtcCA9IHNkKGRpZmZfQXZnVGVtcCwgbmEucm0gPSBUUlVFKQogICkKCiMgVmlldyB0aGUgc3VtbWFyeSBzdGF0aXN0aWNzCnByaW50KHN1bW1hcnlfc3RhdHMyKQpgYGAKClBsb3R0aW5nIHRoZSBtb250aGx5IHRlbXBlcmF0dXJlIGNoYW5nZSBncmFwaHMKCjIwMzBzCmBgYHtyfQpzdW1tYXJ5X3N0YXRzICMgZ3JvdXBlZCBieSBtb250aCBhbmQgcG9uZApzdW1tYXJ5X3N0YXRzMiAjIGdyb3VwZWQgYnkganVzdCBtb250aAoKIyAyLiBNb250aGx5IGF2ZXJhZ2VzIGFjcm9zcyBwb25kcwpNb250aGx5U3RhdHNfMjAzMCA8LSBzdW1tYXJ5X3N0YXRzMiAlPiUKICBmaWx0ZXIoRGVjYWRlID09ICIyMDMwcyIpIAoKZ2dwbG90KGRhdGEgPSBNb250aGx5U3RhdHNfMjAzMCwgYWVzKHggPSBNb250aCkpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gbWVhbl9kaWZmX0F2Z1RlbXApKSArCiAgdGhlbWVfY2xhc3NpYygpCgojIENvbnZlcnQgTW9udGggZnJvbSBjaGFyYWN0ZXIgdG8gbnVtZXJpYyB0byBlbnN1cmUgcHJvcGVyIG9yZGVyaW5nIGluIGdncGxvdApNb250aGx5U3RhdHNfMjAzMCRNb250aCA8LSBhcy5udW1lcmljKE1vbnRobHlTdGF0c18yMDMwJE1vbnRoKQoKIyBQbG90IHVzaW5nIGdncGxvdApNb250aGx5U3RhdHNfMjAzMFBsb3QgPC0gZ2dwbG90KGRhdGEgPSBNb250aGx5U3RhdHNfMjAzMCwgYWVzKHggPSBNb250aCkpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBtZWFuX2RpZmZfQXZnVGVtcCkpICsgICMgUG9pbnQgcGxvdCB3aXRoIG1lYW4gdmFsdWVzCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSArICAjIEhvcml6b250YWwgZGFzaGVkIGxpbmUgYXQgeSA9IDAKICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IG1lYW5fZGlmZl9BdmdUZW1wIC0gc2RfZGlmZl9BdmdUZW1wLCB5bWF4ID0gbWVhbl9kaWZmX0F2Z1RlbXAgKyBzZF9kaWZmX0F2Z1RlbXApLCBmaWxsID0gImJsdWUiLCBhbHBoYSA9IDAuMykgKyAgIyBSaWJib24gZm9yIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBlcnJvciBiYXNlZCBvbiBzZCB2YWx1ZXMKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gMToxMiwgbGFiZWxzID0gbW9udGguYWJiKSArICAjIEFkanVzdCB4LWF4aXMgbGFiZWxzIHRvIHNob3cgbW9udGggYWJicmV2aWF0aW9ucwogIHlsaW0oLTQsNikrCiAgdGhlbWVfY2xhc3NpYygpICsKICBsYWJzKHggPSAiIiwgeSA9ICJEZWx0YSBUZW1wIChDKSIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDY1LCBoanVzdCA9IDEpKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpKQpNb250aGx5U3RhdHNfMjAzMFBsb3QKYGBgCgoyMDYwcwpgYGB7cn0KIyAyLiBNb250aGx5IGF2ZXJhZ2VzIGFjcm9zcyBwb25kcwpNb250aGx5U3RhdHNfMjA2MCA8LSBzdW1tYXJ5X3N0YXRzMiAlPiUKICBmaWx0ZXIoRGVjYWRlID09ICIyMDYwcyIpIAoKZ2dwbG90KGRhdGEgPSBNb250aGx5U3RhdHNfMjA2MCwgYWVzKHggPSBNb250aCkpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gbWVhbl9kaWZmX0F2Z1RlbXApKSArCiAgdGhlbWVfY2xhc3NpYygpCgojIENvbnZlcnQgTW9udGggZnJvbSBjaGFyYWN0ZXIgdG8gbnVtZXJpYyB0byBlbnN1cmUgcHJvcGVyIG9yZGVyaW5nIGluIGdncGxvdApNb250aGx5U3RhdHNfMjA2MCRNb250aCA8LSBhcy5udW1lcmljKE1vbnRobHlTdGF0c18yMDYwJE1vbnRoKQoKIyBQbG90IHVzaW5nIGdncGxvdApNb250aGx5U3RhdHNfMjA2MFBsb3QgPC0gZ2dwbG90KGRhdGEgPSBNb250aGx5U3RhdHNfMjA2MCwgYWVzKHggPSBNb250aCkpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBtZWFuX2RpZmZfQXZnVGVtcCkpICsgICMgUG9pbnQgcGxvdCB3aXRoIG1lYW4gdmFsdWVzCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSArICAjIEhvcml6b250YWwgZGFzaGVkIGxpbmUgYXQgeSA9IDAKICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IG1lYW5fZGlmZl9BdmdUZW1wIC0gc2RfZGlmZl9BdmdUZW1wLCB5bWF4ID0gbWVhbl9kaWZmX0F2Z1RlbXAgKyBzZF9kaWZmX0F2Z1RlbXApLCBmaWxsID0gImJsdWUiLCBhbHBoYSA9IDAuMykgKyAgIyBSaWJib24gZm9yIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBlcnJvciBiYXNlZCBvbiBzZCB2YWx1ZXMKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gMToxMiwgbGFiZWxzID0gbW9udGguYWJiKSArICAjIEFkanVzdCB4LWF4aXMgbGFiZWxzIHRvIHNob3cgbW9udGggYWJicmV2aWF0aW9ucwogIHlsaW0oLTQsNikrCiAgdGhlbWVfY2xhc3NpYygpICsKICBsYWJzKHggPSAiIiwgeSA9ICIiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA2NSwgaGp1c3QgPSAxKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2KSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkrCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksICAjIFJlbW92ZSBZLWF4aXMgdGljayBtYXJrIGxhYmVscwogICAgICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSkKTW9udGhseVN0YXRzXzIwNjBQbG90CmBgYAoyMDkwcwpgYGB7cn0KIyAyLiBNb250aGx5IGF2ZXJhZ2VzIGFjcm9zcyBwb25kcwpNb250aGx5U3RhdHNfMjA5MCA8LSBzdW1tYXJ5X3N0YXRzMiAlPiUKICBmaWx0ZXIoRGVjYWRlID09ICIyMDkwcyIpIAoKZ2dwbG90KGRhdGEgPSBNb250aGx5U3RhdHNfMjA5MCwgYWVzKHggPSBNb250aCkpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gbWVhbl9kaWZmX0F2Z1RlbXApKSArCiAgdGhlbWVfY2xhc3NpYygpCgojIENvbnZlcnQgTW9udGggZnJvbSBjaGFyYWN0ZXIgdG8gbnVtZXJpYyB0byBlbnN1cmUgcHJvcGVyIG9yZGVyaW5nIGluIGdncGxvdApNb250aGx5U3RhdHNfMjA5MCRNb250aCA8LSBhcy5udW1lcmljKE1vbnRobHlTdGF0c18yMDkwJE1vbnRoKQoKIyBQbG90IHVzaW5nIGdncGxvdApNb250aGx5U3RhdHNfMjA5MFBsb3QgPC0gZ2dwbG90KGRhdGEgPSBNb250aGx5U3RhdHNfMjA5MCwgYWVzKHggPSBNb250aCkpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBtZWFuX2RpZmZfQXZnVGVtcCkpICsgICMgUG9pbnQgcGxvdCB3aXRoIG1lYW4gdmFsdWVzCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSArICAjIEhvcml6b250YWwgZGFzaGVkIGxpbmUgYXQgeSA9IDAKICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IG1lYW5fZGlmZl9BdmdUZW1wIC0gc2RfZGlmZl9BdmdUZW1wLCB5bWF4ID0gbWVhbl9kaWZmX0F2Z1RlbXAgKyBzZF9kaWZmX0F2Z1RlbXApLCBmaWxsID0gImJsdWUiLCBhbHBoYSA9IDAuMykgKyAgIyBSaWJib24gZm9yIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBlcnJvciBiYXNlZCBvbiBzZCB2YWx1ZXMKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gMToxMiwgbGFiZWxzID0gbW9udGguYWJiKSArICAjIEFkanVzdCB4LWF4aXMgbGFiZWxzIHRvIHNob3cgbW9udGggYWJicmV2aWF0aW9ucwogIHlsaW0oLTQsNikrCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDY1LCBoanVzdCA9IDEpKSArCiAgbGFicyh4ID0gIiIsIHkgPSAiIikgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2KSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkrCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksICAjIFJlbW92ZSBZLWF4aXMgdGljayBtYXJrIGxhYmVscwogICAgICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSkKTW9udGhseVN0YXRzXzIwOTBQbG90CmBgYAoKQ29tYmluZSB0aGUgcGxvdHMgdG9nZXRoZXIgaGVyZSBmb3Igbm93CmBgYHtyfQojIENvbWJpbmUgcGxvdHMgaW50byBhIHBhbmVsIHBsb3QKRGVsdGFNb250aF9DUkQ0NV9wbG90IDwtIGdnYXJyYW5nZShNb250aGx5U3RhdHNfMjAzMFBsb3QsIE1vbnRobHlTdGF0c18yMDYwUGxvdCwgTW9udGhseVN0YXRzXzIwOTBQbG90LCBuY29sID0gMykKCiMgU2F2ZSB0aGUgY29tYmluZWQgcGxvdApnZ3NhdmUoIkNvcnJfRGVsdGFNb250aENSRDQ1LnBuZyIsIHBsb3QgPSBEZWx0YU1vbnRoX0NSRDQ1X3Bsb3QsIHdpZHRoID0gMTIsIGhlaWdodCA9IDMpCgpgYGAKCkNyZWF0ZSAuY3N2IGZpbGVzIG9mIHRoZSBkYXRhIGZvciB0aGVzZSBncmFwaHMKYGBge3J9CndyaXRlLmNzdihNb250aGx5U3RhdHNfMjAzMCwgZmlsZSA9ICJDb3JyX01vbnRobHlTdGF0c0NSRDQ1XzIwMzAuY3N2IikKd3JpdGUuY3N2KE1vbnRobHlTdGF0c18yMDYwLCBmaWxlID0gIkNvcnJfTW9udGhseVN0YXRzQ1JENDVfMjA2MC5jc3YiKQp3cml0ZS5jc3YoTW9udGhseVN0YXRzXzIwOTAsIGZpbGUgPSAiQ29ycl9Nb250aGx5U3RhdHNDUkQ0NV8yMDkwLmNzdiIpCmBgYAoKCgo=